1
0

Compare commits

...

54 Commits
0.1.1 ... 0.4.1

Author SHA1 Message Date
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
6927ac0e4f Version 0.3.1 2018-04-20 20:39:18 +02:00
2fd5b0f6ee [API] Improve login (#83) 2018-04-20 20:30:39 +02:00
b7a6b71a4d Change message after sync completed (#85) 2018-04-20 14:07:40 +02:00
ce00c7025a Version 0.3.0 2018-04-08 20:16:52 +02:00
5c558ae1f9 Show fully name on expand header (#82) 2018-04-08 18:05:41 +02:00
0708d84b98 Log non-fatal exceptions with fabric (#80) 2018-04-08 17:34:18 +02:00
b22d95392b Update CI config (#81) 2018-04-08 17:14:59 +02:00
78d57ca746 Notifications improvements (#78)
* Refactor notifications
* Change grade notify icon
2018-04-08 16:37:27 +02:00
0aa8c5605d Add setttings (#74) 2018-04-08 16:15:05 +02:00
cb6afb137f Hide actionbar during login (#79) 2018-04-08 15:54:46 +02:00
c72e7748e2 Migrate to ThreeTenABP (#77) 2018-04-05 21:56:08 +02:00
5c9f10fa50 Update gradle to 4.4 (#75) 2018-04-03 16:10:56 +02:00
cdd3d6a53b Version 0.2.2 2018-03-22 22:54:11 +01:00
8431661d54 Fix resuming states in fragments (#72)
* Downgrade sdk version
* Update dependencies
* Fix infinite loading on restore states
* Fix crash when loading loaded fragments
2018-03-22 22:42:08 +01:00
3dabb11473 [API] Add error messages to exceptions (#71) 2018-03-20 23:10:20 +01:00
63b4ed42ca Version 0.2.1 2018-03-14 22:08:57 +01:00
2bb2341d0f Fix display items on refresh (#70) 2018-03-14 21:56:39 +01:00
797e233809 Fix inactive elements (#69) 2018-03-14 20:22:31 +01:00
64b964ca18 Fix circleci instrumented job (#68) 2018-03-13 22:30:33 +01:00
c9bdac6a66 Fix session handling (#67) 2018-03-13 18:19:04 +01:00
83b4f359bc Version 0.2.0 2018-03-11 20:01:45 +01:00
a094d4f0d9 Fix crash in grades on some devices (#66) 2018-03-11 19:31:56 +01:00
3aca34340d Optimize session handling (#63)
* [APP] Change way the Vulcan is configured (#65)
2018-03-11 19:16:20 +01:00
a0313827ce [DB] Add database migrations (#64) 2018-03-11 18:18:33 +01:00
3799fa910b Add attendance (#58) 2018-03-10 15:55:34 +01:00
828e76821b Replace versioneye with snyk (#62) 2018-03-10 14:04:00 +01:00
e050982de2 Add application id suffix in debug builds (#61) 2018-03-10 13:08:01 +01:00
69fc4bf874 Add cleaning user data on upgrade and downgrade (#60) 2018-03-06 20:14:54 +01:00
c3803b1c96 Add a view of free days to the timetable (#57)
* Fix Timetable freeze when app was killed
* Add views for free days
2018-03-06 00:57:06 +01:00
e274949257 Add remove user id in db upgrade (#59) 2018-03-06 00:25:12 +01:00
256 changed files with 9352 additions and 2762 deletions

View File

@ -7,7 +7,7 @@ references:
container_config: &container_config
docker:
- image: circleci/android:api-27-alpha
- image: circleci/android:api-26-alpha
working_directory: *workspace_root
environment:
environment:
@ -31,9 +31,18 @@ jobs:
- run:
name: Setup environment
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:
name: Initial build
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:
path: ./app/build/outputs/apk/
destination: apks/
@ -126,6 +135,9 @@ jobs:
name: Launch emulator
command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel on
background: true
- run:
name: Change circle-android script file permissions
command: sudo chmod +rx /bin/circle-android
- run:
name: Wait emulator
command: |
@ -169,6 +181,21 @@ jobs:
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
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:
version: 2
@ -196,3 +223,9 @@ workflows:
- app-test
- api-test
- instrumented
- deploy:
requires:
- instrumented
filters:
branches:
only: master

6
.gitignore vendored
View File

@ -32,6 +32,8 @@ local.properties
.idea/tasks.xml
.idea/vcs.xml
.idea/workspace.xml
.idea/caches/
.idea/codeStyles/
*.iml
# OS-specific files
@ -42,3 +44,7 @@ local.properties
.Trashes
ehthumbs.db
Thumbs.db
.idea/codeStyles/
.idea/caches/
./app/key.p12
./app/upload-key.jks

View File

@ -12,7 +12,7 @@ build:
script:
- ./gradlew --no-daemon --stacktrace dependencies || true
- ./gradlew --no-daemon --stacktrace assembleDebug
- mv app/build/outputs/apk/app-debug.apk .
- mv app/build/outputs/apk/debug/app-debug.apk .
artifacts:
name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}"
paths:
@ -26,7 +26,7 @@ tests:
- .gradle
policy: pull
script:
- ./gradlew --no-daemon --stacktrace test
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease test
artifacts:
paths:
- app/build/reports/tests
@ -39,7 +39,7 @@ lint:
- .gradle
policy: pull
script:
- ./gradlew --no-daemon --stacktrace lint
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease lint
artifacts:
paths:
- app/build/reports

View File

@ -1,12 +1,15 @@
# Wulkanowy
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Dependency Status](https://www.versioneye.com/user/projects/5969ff0b0fb24f004f8c711b/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/5969ff0b0fb24f004f8c711b)
[![CircleCI](https://img.shields.io/circleci/project/github/wulkanowy/wulkanowy.svg?style=flat-square)](https://circleci.com/gh/wulkanowy/wulkanowy)
[![CircleCI](https://img.shields.io/circleci/project/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://circleci.com/gh/wulkanowy/wulkanowy)
[![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)
[![BCH compliance](https://bettercodehub.com/edge/badge/wulkanowy/wulkanowy?branch=master)](https://bettercodehub.com/)
[![Scrutinizer](https://img.shields.io/scrutinizer/g/wulkanowy/wulkanowy.svg?style=flat-square)](https://scrutinizer-ci.com/g/wulkanowy/wulkanowy/?branch=master)
[![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/JMG2rhJ)
[Pobierz wersję rozwojową](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/app-release-bitrise-signed.apk)
[Pobierz wersję beta](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs)
Wulkanowy to projekt aplikacji na androida ułatwiającej używanie dziennika VULCANa.
[Pobierz wersję rozwojową](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/app-debug-bitrise-signed.apk)
Androidowy klient dziennika VULCAN UONET+.

View File

@ -5,7 +5,7 @@ sonarqube {
//noinspection GroovyAssignabilityCheck
properties {
def files = fileTree("${rootProject.projectDir}/api/build/libs/").filter { it.isFile() }.files.name
def libraries = project.android.sdkDirectory.getPath() + "/platforms/android-27/android.jar," +
def libraries = project.android.sdkDirectory.getPath() + "/platforms/android-26/android.jar," +
"${project.rootDir}/api/build/libs/" + files[0]
property "sonar.projectName", GROUP_ID + ":app"

View File

@ -28,12 +28,12 @@ jacocoTestReport {
}
dependencies {
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'org.apache.commons:commons-lang3:3.7'
implementation 'com.google.code.gson:gson:2.8.2'
implementation "org.jsoup:jsoup:$jsoup"
implementation "org.apache.commons:commons-lang3:$apacheLang"
implementation "com.google.code.gson:gson:$gson"
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.13.0'
testImplementation "junit:junit:$junit"
testImplementation "org.mockito:mockito-core:$mockito"
}
version = PUBLISH_VERSION

View File

@ -5,44 +5,113 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.github.wulkanowy.api.login.Login;
public class Client {
private String protocol;
private String protocol = "https";
private String host;
private String host = "vulcan.net.pl";
private String email;
private String password;
private String symbol;
private Date lastSuccessRequest;
private Cookies cookies = new Cookies();
Client(String protocol, String host, String symbol) {
this.protocol = protocol;
this.host = host;
Client(String email, String password, String symbol) {
this.email = email;
this.password = password;
this.symbol = symbol;
setFullEndpointInfo(email);
}
String getHost() {
return host;
private void setFullEndpointInfo(String info) {
String[] creds = info.split("\\\\");
email = info;
if (creds.length > 2) {
String[] url = creds[0].split("://");
protocol = url[0];
String[] path = url[1].split("/");
host = path[0];
if (path.length > 1) {
symbol = path[1];
}
email = creds[2];
}
}
private void login() throws IOException, VulcanException {
if (isLoggedIn()) {
return;
}
this.cookies = new Cookies();
this.symbol = new Login(this).login(email, password, symbol);
}
private boolean isLoggedIn() {
return getCookies().size() > 0 && lastSuccessRequest != null &&
29 > TimeUnit.MILLISECONDS.toMinutes(new Date().getTime() - lastSuccessRequest.getTime());
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
Map<String, String> getCookies() {
public void addCookies(Map<String, String> items) {
cookies.addItems(items);
}
private Map<String, String> getCookies() {
return cookies.getItems();
}
private String getFilledUrl(String url) {
String getHost() {
return host;
}
String getFilledUrl(String url) {
return url
.replace("{schema}", protocol)
.replace("{host}", host.replace(":", "%253A"))
.replace("{symbol}", symbol == null ? "Default" : symbol);
.replace("{symbol}", symbol);
}
Document getPageByUrl(String url) throws IOException {
public Document getPageByUrl(String url) throws IOException, VulcanException {
return getPageByUrl(url, true, null);
}
public Document getPageByUrl(String url, boolean loginBefore) throws IOException, VulcanException {
return getPageByUrl(url, loginBefore, null);
}
public synchronized Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException {
if (loginBefore) {
login();
}
if (null != cookies) {
this.cookies.addItems(cookies);
}
Connection.Response response = Jsoup.connect(getFilledUrl(url))
.followRedirects(true)
.cookies(getCookies())
@ -50,10 +119,16 @@ public class Client {
this.cookies.addItems(response.cookies());
return response.parse();
Document doc = checkForErrors(response.parse());
if (loginBefore) {
lastSuccessRequest = new Date();
}
return doc;
}
public Document postPageByUrl(String url, String[][] params) throws IOException {
public synchronized Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException {
Connection connection = Jsoup.connect(getFilledUrl(url));
for (String[] data : params) {
@ -68,10 +143,12 @@ public class Client {
this.cookies.addItems(response.cookies());
return response.parse();
return checkForErrors(response.parse());
}
public String getJsonStringByUrl(String url) throws IOException {
public String getJsonStringByUrl(String url) throws IOException, VulcanException {
login();
Connection.Response response = Jsoup.connect(getFilledUrl(url))
.followRedirects(true)
.ignoreContentType(true)
@ -83,7 +160,9 @@ public class Client {
return response.body();
}
public String postJsonStringByUrl(String url, String[][] params) throws IOException {
public String postJsonStringByUrl(String url, String[][] params) throws IOException, VulcanException {
login();
Connection connection = Jsoup.connect(getFilledUrl(url));
for (String[] data : params) {
@ -101,4 +180,24 @@ public class Client {
return response.body();
}
Document checkForErrors(Document doc) throws VulcanException {
lastSuccessRequest = null;
String title = doc.select("title").text();
if ("Przerwa techniczna".equals(title)) {
throw new VulcanOfflineException(title);
}
String singIn = doc.select(".loginButton").text();
if ("Zaloguj się".equals(singIn)) {
throw new NotLoggedInErrorException(singIn);
}
if ("Błąd strony".equals(title)) {
throw new VulcanException("Nieznany błąd");
}
return doc;
}
}

View File

@ -3,21 +3,15 @@ package io.github.wulkanowy.api;
import java.util.HashMap;
import java.util.Map;
public class Cookies {
class Cookies {
private Map<String, String> jar = new HashMap<>();
public Map<String, String> getItems() {
Map<String, String> getItems() {
return jar;
}
public Cookies setItems(Map<String, String> items) {
this.jar = items;
return this;
}
public Cookies addItems(Map<String, String> items) {
this.jar.putAll(items);
return this;
void addItems(Map<String, String> items) {
jar.putAll(items);
}
}

View File

@ -0,0 +1,38 @@
package io.github.wulkanowy.api;
public class Diary implements ParamItem {
private String id = "";
private String name = "";
private boolean current = false;
public String getId() {
return id;
}
public Diary setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Diary setName(String name) {
this.name = name;
return this;
}
@Override
public boolean isCurrent() {
return current;
}
public Diary setCurrent(boolean current) {
this.current = current;
return this;
}
}

View File

@ -0,0 +1,8 @@
package io.github.wulkanowy.api;
public class NotLoggedInErrorException extends VulcanException {
public NotLoggedInErrorException(String message) {
super(message);
}
}

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.api;
interface ParamItem {
ParamItem setId(String id);
ParamItem setName(String name);
ParamItem setCurrent(boolean isCurrent);
boolean isCurrent();
}

View File

@ -1,21 +1,12 @@
package io.github.wulkanowy.api;
public class Semester {
private String number = "";
public class Semester implements ParamItem {
private String id = "";
private boolean isCurrent = false;
private String name = "";
public String getNumber() {
return number;
}
public Semester setNumber(String number) {
this.number = number;
return this;
}
private boolean current = false;
public String getId() {
return id;
@ -26,12 +17,21 @@ public class Semester {
return this;
}
public String getName() {
return name;
}
public Semester setName(String number) {
this.name = number;
return this;
}
public boolean isCurrent() {
return isCurrent;
return current;
}
public Semester setCurrent(boolean current) {
isCurrent = current;
this.current = current;
return this;
}
}

View File

@ -6,21 +6,27 @@ import org.jsoup.nodes.Element;
import java.io.IOException;
import java.util.List;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
public interface SnP {
String getId();
String getSchoolID();
void storeContextCookies() throws IOException, NotLoggedInErrorException;
void setDiaryID(String id);
String getStudentID();
List<Student> getStudents() throws IOException, VulcanException;
StudentAndParent setUp() throws IOException, VulcanException;
String getRowDataChildValue(Element e, int index);
Document getSnPPageDocument(String url) throws IOException;
Document getSnPPageDocument(String url) throws IOException, VulcanException;
List<Semester> getSemesters() throws IOException;
List<Diary> getDiaries() throws IOException, VulcanException;
List<Semester> getSemesters() throws IOException, VulcanException;
List<Semester> getSemesters(Document gradesPage);
Semester getCurrentSemester(List<Semester> semesterList);
<T> T getCurrent(List<? extends ParamItem> list);
}

View File

@ -0,0 +1,37 @@
package io.github.wulkanowy.api;
public class Student implements ParamItem {
private String id = "";
private String name = "";
private boolean current = false;
public String getId() {
return id;
}
public Student setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public boolean isCurrent() {
return current;
}
public Student setCurrent(boolean current) {
this.current = current;
return this;
}
}

View File

@ -5,10 +5,11 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import java.util.Map;
public class StudentAndParent implements SnP {
@ -20,31 +21,47 @@ public class StudentAndParent implements SnP {
private Client client;
private String id;
private String schoolID;
StudentAndParent(Client client) {
private String studentID;
private String diaryID;
StudentAndParent(Client client, String schoolID, String studentID, String diaryID) {
this.client = client;
this.schoolID = schoolID;
this.studentID = studentID;
this.diaryID = diaryID;
}
StudentAndParent(Client client, String id) {
this(client);
this.id = id;
public StudentAndParent setUp() throws IOException, VulcanException {
if (null == getStudentID() || "".equals(getStudentID())) {
Document doc = client.getPageByUrl(getSnpHomePageUrl());
Student student = getCurrent(getStudents(doc));
studentID = student.getId();
Diary diary = getCurrent(getDiaries(doc));
diaryID = diary.getId();
}
return this;
}
public String getSchoolID() {
return schoolID;
}
public String getStudentID() {
return studentID;
}
private String getBaseUrl() {
return BASE_URL.replace("{ID}", getId());
return BASE_URL.replace("{ID}", getSchoolID());
}
public String getId() {
return id;
}
public void storeContextCookies() throws IOException, NotLoggedInErrorException {
client.getPageByUrl(getSnpHomePageUrl());
}
String getSnpHomePageUrl() throws IOException, NotLoggedInErrorException {
if (null != getId()) {
String getSnpHomePageUrl() throws IOException, VulcanException {
if (null != getSchoolID()) {
return getBaseUrl();
}
@ -53,12 +70,12 @@ public class StudentAndParent implements SnP {
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first();
if (null == studentTileLink) {
throw new NotLoggedInErrorException();
throw new NotLoggedInErrorException("You are probably not logged in. Force login");
}
String snpPageUrl = studentTileLink.attr("href");
this.id = getExtractedIdFromUrl(snpPageUrl);
this.schoolID = getExtractedIdFromUrl(snpPageUrl);
return snpPageUrl;
}
@ -67,7 +84,7 @@ public class StudentAndParent implements SnP {
String[] path = snpPageUrl.split(client.getHost())[1].split("/");
if (5 != path.length) {
throw new NotLoggedInErrorException();
throw new NotLoggedInErrorException("You are probably not logged in");
}
return path[2];
@ -77,11 +94,46 @@ public class StudentAndParent implements SnP {
return e.select(".daneWiersz .wartosc").get(index - 1).text();
}
public Document getSnPPageDocument(String url) throws IOException {
return client.getPageByUrl(getBaseUrl() + url);
public void setDiaryID(String id) {
this.diaryID = id;
}
public List<Semester> getSemesters() throws IOException {
public Document getSnPPageDocument(String url) throws IOException, VulcanException {
Map<String, String> cookies = new HashMap<>();
cookies.put("idBiezacyDziennik", diaryID);
cookies.put("idBiezacyUczen", studentID);
client.addCookies(cookies);
Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies);
if (!doc.title().startsWith("Witryna ucznia i rodzica")) {
throw new VulcanException("Expected SnP page, got page with title: " + doc.title());
}
if (doc.title().endsWith("Strona główna")) {
throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
}
return doc;
}
public List<Diary> getDiaries() throws IOException, VulcanException {
return getDiaries(client.getPageByUrl(getBaseUrl()));
}
private List<Diary> getDiaries(Document doc) throws IOException, VulcanException {
return getList(doc.select("#dziennikDropDownList option"), Diary.class);
}
public List<Student> getStudents() throws IOException, VulcanException {
return getStudents(client.getPageByUrl(getBaseUrl()));
}
private List<Student> getStudents(Document doc) throws IOException, VulcanException {
return getList(doc.select("#uczenDropDownList option"), Student.class);
}
public List<Semester> getSemesters() throws IOException, VulcanException {
return getSemesters(getSnPPageDocument(GRADES_PAGE_URL));
}
@ -92,10 +144,10 @@ public class StudentAndParent implements SnP {
for (Element e : semesterOptions) {
Semester semester = new Semester()
.setId(e.text())
.setNumber(e.attr("value"));
.setId(e.attr("value"))
.setName(e.text());
if ("selected".equals(e.attr("selected"))) {
if (isCurrent(e)) {
semester.setCurrent(true);
}
@ -105,15 +157,44 @@ public class StudentAndParent implements SnP {
return semesters;
}
public Semester getCurrentSemester(List<Semester> semesterList) {
Semester current = null;
for (Semester s : semesterList) {
@SuppressWarnings("unchecked")
private <T> List<T> getList(Elements options, Class<? extends ParamItem> type) throws IOException, VulcanException {
List<T> list = new ArrayList<>();
for (Element e : options) {
URL url = new URL(e.val());
try {
ParamItem item = type.newInstance()
.setId(url.getQuery().split("=")[1])
.setName(e.text());
if (isCurrent(e)) {
item.setCurrent(true);
}
list.add((T) item);
} catch (Exception ex) {
throw new VulcanException("Error while trying to parse params list", ex);
}
}
return list;
}
@SuppressWarnings("unchecked")
public <T> T getCurrent(List<? extends ParamItem> list) {
ParamItem current = null;
for (ParamItem s : list) {
if (s.isCurrent()) {
current = s;
break;
}
}
return current;
return (T) current;
}
private boolean isCurrent(Element e) {
return "selected".equals(e.attr("selected"));
}
}

View File

@ -7,12 +7,6 @@ import io.github.wulkanowy.api.attendance.AttendanceTable;
import io.github.wulkanowy.api.exams.ExamsWeek;
import io.github.wulkanowy.api.grades.GradesList;
import io.github.wulkanowy.api.grades.SubjectsList;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.api.login.VulcanOfflineException;
import io.github.wulkanowy.api.messages.Messages;
import io.github.wulkanowy.api.notes.AchievementsList;
import io.github.wulkanowy.api.notes.NotesList;
@ -24,173 +18,97 @@ import io.github.wulkanowy.api.user.FamilyInformation;
public class Vulcan {
private String id;
private String symbol;
private SnP snp;
private String protocolSchema = "https";
private String logHost = "vulcan.net.pl";
private String email;
private Client client;
private Login login;
private String schoolId;
public void setClient(Client client) {
this.client = client;
private String studentId;
private String diaryId;
public void setCredentials(String email, String password, String symbol, String schoolId, String studentId, String diaryId) {
this.schoolId = schoolId;
this.studentId = studentId;
this.diaryId = diaryId;
client = new Client(email, password, symbol);
}
public void setLogin(Login login) {
this.login = login;
}
public void login(String email, String password, String symbol)
throws BadCredentialsException, AccountPermissionException,
LoginErrorException, IOException, VulcanOfflineException {
setFullEndpointInfo(email);
login = getLogin();
this.symbol = login.login(this.email, password, symbol);
}
public Vulcan login(String email, String password, String symbol, String id)
throws BadCredentialsException, AccountPermissionException,
LoginErrorException, IOException, VulcanOfflineException {
login(email, password, symbol);
this.id = id;
return this;
}
String getProtocolSchema() {
return protocolSchema;
}
String getLogHost() {
return logHost;
}
public String getEmail() {
return email;
}
public String getSymbol() {
return symbol;
}
private void setFullEndpointInfo(String email) {
String[] creds = email.split("\\\\");
this.email = email;
if (creds.length >= 2) {
String[] url = creds[0].split("://");
this.protocolSchema = url[0];
this.logHost = url[1];
this.email = creds[2];
public Client getClient() throws NotLoggedInErrorException {
if (null == client) {
throw new NotLoggedInErrorException("Use setCredentials() method first");
}
}
protected Client getClient() {
if (null != client) {
return client;
}
client = new Client(getProtocolSchema(), getLogHost(), symbol);
return client;
}
protected Login getLogin() {
if (null != login) {
return login;
}
public String getSymbol() throws NotLoggedInErrorException {
return getClient().getSymbol();
login = new Login(getClient());
return login;
}
public SnP getStudentAndParent() throws IOException, NotLoggedInErrorException {
if (0 == getClient().getCookies().size()) {
throw new NotLoggedInErrorException();
public SnP getStudentAndParent() throws VulcanException, IOException {
if (null != this.snp) {
return this.snp;
}
if (null != snp) {
return snp;
}
this.snp = new StudentAndParent(getClient(), schoolId, studentId, diaryId)
.setUp();
snp = createSnp(getClient(), id);
snp.storeContextCookies();
return snp;
return this.snp;
}
SnP createSnp(Client client, String id) {
if (null == id) {
return new StudentAndParent(client);
}
return new StudentAndParent(client, id);
}
public AttendanceStatistics getAttendanceStatistics() throws IOException, NotLoggedInErrorException {
return new AttendanceStatistics(getStudentAndParent());
}
public AttendanceTable getAttendanceTable() throws IOException, NotLoggedInErrorException {
public AttendanceTable getAttendanceTable() throws IOException, VulcanException {
return new AttendanceTable(getStudentAndParent());
}
public ExamsWeek getExamsList() throws IOException, NotLoggedInErrorException {
public AttendanceStatistics getAttendanceStatistics() throws IOException, VulcanException {
return new AttendanceStatistics(getStudentAndParent());
}
public ExamsWeek getExamsList() throws IOException, VulcanException {
return new ExamsWeek(getStudentAndParent());
}
public GradesList getGradesList() throws IOException, NotLoggedInErrorException {
public GradesList getGradesList() throws IOException, VulcanException {
return new GradesList(getStudentAndParent());
}
public SubjectsList getSubjectsList() throws IOException, NotLoggedInErrorException {
public SubjectsList getSubjectsList() throws IOException, VulcanException {
return new SubjectsList(getStudentAndParent());
}
public AchievementsList getAchievementsList() throws IOException, NotLoggedInErrorException {
public AchievementsList getAchievementsList() throws IOException, VulcanException {
return new AchievementsList(getStudentAndParent());
}
public NotesList getNotesList() throws IOException, NotLoggedInErrorException {
public NotesList getNotesList() throws IOException, VulcanException {
return new NotesList(getStudentAndParent());
}
public SchoolInfo getSchoolInfo() throws IOException, NotLoggedInErrorException {
public SchoolInfo getSchoolInfo() throws IOException, VulcanException {
return new SchoolInfo(getStudentAndParent());
}
public TeachersInfo getTeachersInfo() throws IOException, NotLoggedInErrorException {
public TeachersInfo getTeachersInfo() throws IOException, VulcanException {
return new TeachersInfo(getStudentAndParent());
}
public Timetable getTimetable() throws IOException, NotLoggedInErrorException {
public Timetable getTimetable() throws IOException, VulcanException {
return new Timetable(getStudentAndParent());
}
public BasicInformation getBasicInformation() throws IOException, NotLoggedInErrorException {
public BasicInformation getBasicInformation() throws IOException, VulcanException {
return new BasicInformation(getStudentAndParent());
}
public FamilyInformation getFamilyInformation() throws IOException, NotLoggedInErrorException {
public FamilyInformation getFamilyInformation() throws IOException, VulcanException {
return new FamilyInformation(getStudentAndParent());
}
public Messages getMessages() {
public Messages getMessages() throws VulcanException {
return new Messages(getClient());
}
}

View File

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

View File

@ -0,0 +1,8 @@
package io.github.wulkanowy.api;
public class VulcanOfflineException extends VulcanException {
VulcanOfflineException(String message) {
super(message);
}
}

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.generic.Month;
import io.github.wulkanowy.api.generic.Subject;
@ -22,15 +23,15 @@ public class AttendanceStatistics {
this.snp = snp;
}
public Types getTypesTable() throws IOException {
public Types getTypesTable() throws IOException, VulcanException {
return getTypesTable("");
}
public Types getTypesTable(String tick) throws IOException {
public Types getTypesTable(String tick) throws IOException, VulcanException {
return getTypesTable(tick, -1);
}
public List<Subject> getSubjectList() throws IOException {
public List<Subject> getSubjectList() throws IOException, VulcanException {
Element mainContainer = snp.getSnPPageDocument(attendancePageUrl)
.select(".mainContainer #idPrzedmiot").first();
@ -46,7 +47,7 @@ public class AttendanceStatistics {
return subjectList;
}
public Types getTypesTable(String tick, Integer subjectId) throws IOException {
public Types getTypesTable(String tick, Integer subjectId) throws IOException, VulcanException {
Element mainContainer = snp.getSnPPageDocument((attendancePageUrl
+ "?data={tick}&idPrzedmiot={subject}")
.replace("{tick}", tick)

View File

@ -4,37 +4,52 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import io.github.wulkanowy.api.SnP;
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.Week;
public class AttendanceTable {
private SnP snp;
private final static String ATTENDANCE_PAGE_URL = "Frekwencja.mvc?data=";
private String attendancePageUrl = "Frekwencja.mvc?data=";
private SnP snp;
public AttendanceTable(SnP snp) {
this.snp = snp;
}
public Week<Day> getWeekTable() throws IOException {
public Week<Day> getWeekTable() throws IOException, ParseException, VulcanException {
return getWeekTable("");
}
public Week<Day> getWeekTable(String tick) throws IOException {
Element table = snp.getSnPPageDocument(attendancePageUrl + tick)
public Week<Day> getWeekTable(String tick) throws IOException, ParseException, VulcanException {
Element table = snp.getSnPPageDocument(ATTENDANCE_PAGE_URL + tick)
.select(".mainContainer .presentData").first();
Elements headerCells = table.select("thead th");
List<Day> days = new ArrayList<>();
for (int i = 1; i < headerCells.size(); i++) {
days.add(new Day().setDate(headerCells.get(i).html().split("<br>")[1]));
String[] dayHeaderCell = headerCells.get(i).html().split("<br>");
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
Date d = sdf.parse(dayHeaderCell[1].trim());
sdf.applyPattern("yyyy-MM-dd");
Day day = new Day();
day.setDayName(dayHeaderCell[0]);
day.setDate(sdf.format(d));
days.add(day);
}
Elements hoursInDays = table.select("tbody tr");
@ -46,26 +61,29 @@ public class AttendanceTable {
// fill hours in day
int size = hours.size();
for (int i = 1; i < size; i++) {
days.get(i - 1).setLesson(getNewLesson(hours.get(i)));
Lesson lesson = new Lesson();
lesson.setDate(days.get(i - 1).getDate());
lesson.setNumber(hours.get(0).text());
addLessonDetails(lesson, hours.get(i));
days.get(i - 1).setLesson(lesson);
}
}
String[] dayDescription = headerCells.get(1).html().split("<br>");
return new Week<Day>()
.setStartDayDate(dayDescription[1])
.setStartDayDate(days.get(0).getDate())
.setDays(days);
}
private Lesson getNewLesson(Element cell) {
Lesson lesson = new Lesson();
private void addLessonDetails(Lesson lesson, Element cell) {
lesson.setSubject(cell.select("span").text());
if (LessonTypes.CLASS_NOT_EXIST.equals(cell.attr("class"))) {
lesson.setNotExist(true);
lesson.setEmpty(true);
return lesson;
return;
}
switch (cell.select("div").attr("class")) {
@ -95,7 +113,5 @@ public class AttendanceTable {
lesson.setEmpty(true);
break;
}
return lesson;
}
}

View File

@ -1,14 +1,20 @@
package io.github.wulkanowy.api.exams;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.generic.Week;
public class ExamsWeek {
@ -21,11 +27,11 @@ public class ExamsWeek {
this.snp = snp;
}
public Week<ExamDay> getCurrent() throws IOException {
public Week<ExamDay> getCurrent() throws IOException, VulcanException, ParseException {
return getWeek("", true);
}
public Week<ExamDay> getWeek(String tick, final boolean onlyNotEmpty) throws IOException {
public Week<ExamDay> getWeek(String tick, final boolean onlyNotEmpty) throws IOException, VulcanException, ParseException {
Document examsPage = snp.getSnPPageDocument(EXAMS_PAGE_URL + tick);
Elements examsDays = examsPage.select(".mainContainer > div:not(.navigation)");
@ -40,7 +46,9 @@ public class ExamsWeek {
}
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");
@ -50,15 +58,24 @@ public class ExamsWeek {
.setType(snp.getRowDataChildValue(e, 2))
.setDescription(snp.getRowDataChildValue(e, 3))
.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);
}
return new Week<ExamDay>()
.setStartDayDate(examsDays.select("h2").first().text().split(" ")[1])
.setStartDayDate(getFormattedDate(examsPage.select(".mainContainer > h2")
.first().text().split(" ")[1]))
.setDays(days);
}
private String getFormattedDate(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

@ -11,10 +11,6 @@ public class Day {
private String dayName = "";
private boolean isFreeDay = false;
private String freeDayName = "";
public Lesson getLesson(int index) {
return lessons.get(index);
}
@ -44,20 +40,4 @@ public class Day {
public void setDayName(String dayName) {
this.dayName = dayName;
}
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

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

View File

@ -14,14 +14,14 @@ import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.wulkanowy.api.Semester;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class GradesList {
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie?details=2&okres=";
private SnP snp = null;
private SnP snp;
private List<Grade> grades = new ArrayList<>();
@ -33,50 +33,61 @@ public class GradesList {
return GRADES_PAGE_URL;
}
public List<Grade> getAll() throws IOException, ParseException {
public List<Grade> getAll() throws IOException, ParseException, VulcanException {
return getAll("");
}
public List<Grade> getAll(String semester) throws IOException, ParseException {
public List<Grade> getAll(String semester) throws IOException, ParseException, VulcanException {
Document gradesPage = snp.getSnPPageDocument(getGradesPageUrl() + semester);
Elements gradesRows = gradesPage.select(".ocenySzczegoly-table > tbody > tr");
Semester currentSemester = snp.getCurrentSemester(snp.getSemesters(gradesPage));
for (Element row : gradesRows) {
if ("Brak ocen".equals(row.select("td:nth-child(2)").text())) {
continue;
}
String descriptions = row.select("td:nth-child(3)").text();
String symbol = descriptions.split(", ")[0];
String description = descriptions.replaceFirst(symbol, "").replaceFirst(", ", "");
Pattern pattern = Pattern.compile("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})");
Matcher matcher = pattern.matcher(row.select("td:nth-child(2) span.ocenaCzastkowa")
.attr("style"));
String color = "";
while (matcher.find()) {
color = matcher.group(1);
}
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
Date d = sdf.parse(row.select("td:nth-child(5)").text());
sdf.applyPattern("yyyy-MM-dd");
grades.add(new Grade()
.setSubject(row.select("td:nth-child(1)").text())
.setValue(row.select("td:nth-child(2)").text())
.setColor(color)
.setSymbol(symbol)
.setDescription(description)
.setWeight(row.select("td:nth-child(4)").text())
.setDate(sdf.format(d))
.setTeacher(row.select("td:nth-child(6)").text())
.setSemester(currentSemester.getNumber())
);
grades.add(getGrade(row));
}
return grades;
}
private Grade getGrade(Element row) throws ParseException {
String descriptions = row.select("td:nth-child(3)").text();
String symbol = descriptions.split(", ")[0];
String description = descriptions.replaceFirst(Pattern.quote(symbol), "").replaceFirst(", ", "");
String color = getColor(row.select("td:nth-child(2) span.ocenaCzastkowa").attr("style"));
String date = formatDate(row.select("td:nth-child(5)").text());
return new Grade()
.setSubject(row.select("td:nth-child(1)").text())
.setValue(row.select("td:nth-child(2)").text())
.setColor(color)
.setSymbol(symbol)
.setDescription(description)
.setWeight(row.select("td:nth-child(4)").text())
.setDate(date)
.setTeacher(row.select("td:nth-child(6)").text());
}
private String getColor(String styleAttr) {
Pattern pattern = Pattern.compile("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})");
Matcher matcher = pattern.matcher(styleAttr);
String color = "";
while (matcher.find()) {
color = matcher.group(1);
}
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

@ -9,19 +9,25 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
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) {
this.snp = snp;
}
public List<Subject> getAll() throws IOException {
Document subjectPage = snp.getSnPPageDocument(SUBJECTS_PAGE_URL);
public List<Subject> getAll() throws IOException, VulcanException {
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");

View File

@ -1,4 +1,10 @@
package io.github.wulkanowy.api.login;
public class AccountPermissionException extends Exception {
import io.github.wulkanowy.api.VulcanException;
public class AccountPermissionException extends VulcanException {
AccountPermissionException(String message) {
super(message);
}
}

View File

@ -1,4 +1,10 @@
package io.github.wulkanowy.api.login;
public class BadCredentialsException extends Exception {
import io.github.wulkanowy.api.VulcanException;
public class BadCredentialsException extends VulcanException {
BadCredentialsException(String message) {
super(message);
}
}

View File

@ -2,81 +2,122 @@ package io.github.wulkanowy.api.login;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import java.io.IOException;
import io.github.wulkanowy.api.Client;
import io.github.wulkanowy.api.VulcanException;
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" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx%26wctx%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
private static final String LOGIN_ENDPOINT_PAGE_URL =
"{schema}://uonetplus.{host}/{symbol}/LoginEndpoint.aspx";
private Client client;
private String symbol;
public Login(Client client) {
this.client = client;
}
public String login(String email, String password, String symbol)
throws BadCredentialsException, LoginErrorException,
AccountPermissionException, IOException, VulcanOfflineException {
String certificate = sendCredentials(email, password, symbol);
public String login(String email, String password, String symbol) throws VulcanException, IOException {
Document certDoc = sendCredentials(email, password);
return sendCertificate(certificate, symbol);
return sendCertificate(certDoc, symbol);
}
String sendCredentials(String email, String password, String symbol)
throws IOException, BadCredentialsException {
this.symbol = symbol;
Document html = client.postPageByUrl(LOGIN_PAGE_URL, new String[][]{
Document sendCredentials(String email, String password) throws IOException, VulcanException {
String[][] credentials = new String[][]{
{"LoginName", email},
{"Password", password}
});
};
if (null != html.select(".ErrorMessage").first()) {
throw new BadCredentialsException();
String nextUrl = LOGIN_PAGE_URL;
Document loginPage = client.getPageByUrl(nextUrl, false);
Element formFirst = loginPage.select("#form1").first();
if (null != formFirst) { // on adfs login
Document formSecond = client.postPageByUrl(
formFirst.attr("abs:action"),
getFormStateParams(formFirst, "", "")
);
credentials = getFormStateParams(formSecond, email, password);
nextUrl = formSecond.select("#form1").first().attr("abs:action");
} else if (!"Logowanie".equals(loginPage.select("#h1Default").text())) {
throw new VulcanException("Expected login page, got page with title: " + loginPage.title());
}
return html.select("input[name=wresult]").attr("value");
Document html = client.postPageByUrl(nextUrl, credentials);
Element errorMessage = html.select(".ErrorMessage, #ErrorTextLabel").first();
if (null != errorMessage) {
throw new BadCredentialsException(errorMessage.text());
}
return html;
}
String sendCertificate(String certificate, String defaultSymbol)
throws IOException, LoginErrorException, AccountPermissionException, VulcanOfflineException {
this.symbol = findSymbol(defaultSymbol, certificate);
client.setSymbol(this.symbol);
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},
};
}
Document html = client.postPageByUrl(LOGIN_ENDPOINT_PAGE_URL, new String[][]{
String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
String certificate = doc.select("input[name=wresult]").val();
if ("".equals(certificate)) {
throw new VulcanException("Expected certificate, got empty string. Page title: " + doc.title());
}
client.setSymbol(findSymbol(defaultSymbol, certificate));
Document targetDoc = sendCertData(doc);
String title = targetDoc.title();
if ("Working...".equals(title)) { // on adfs login
title = sendCertData(targetDoc).title();
}
if ("Logowanie".equals(title)) {
throw new AccountPermissionException("No account access. Try another symbol");
}
if (!"Uonet+".equals(title)) {
throw new LoginErrorException("Expected page title `UONET+`, got " + title);
}
return client.getSymbol();
}
private Document sendCertData(Document doc) throws IOException, VulcanException {
String url = doc.select("form[name=hiddenform]").attr("action");
if (!doc.title().equals("Working...")) {
throw new VulcanException("Expected certificate page, got page with title: " + doc.title());
}
return client.postPageByUrl(url.replaceFirst("Default", "{symbol}"), new String[][]{
{"wa", "wsignin1.0"},
{"wresult", certificate}
{"wresult", doc.select("input[name=wresult]").val()},
{"wctx", doc.select("input[name=wctx]").val()}
});
if (html.getElementsByTag("title").text().equals("Logowanie")) {
throw new AccountPermissionException();
}
if (html.getElementsByTag("title").text().equals("Przerwa techniczna")) {
throw new VulcanOfflineException();
}
if (!html.select("title").text().equals("Uonet+")) {
throw new LoginErrorException();
}
return this.symbol;
}
private String findSymbol(String symbol, String certificate) {
private String findSymbol(String symbol, String certificate) throws AccountPermissionException {
if ("Default".equals(symbol)) {
return findSymbolInCertificate(certificate);
}
@ -84,14 +125,15 @@ public class Login {
return symbol;
}
String findSymbolInCertificate(String certificate) {
Elements els = Jsoup.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
String findSymbolInCertificate(String certificate) throws AccountPermissionException {
Elements instances = Jsoup
.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
.select("[AttributeName=\"UserInstance\"] samlAttributeValue");
if (els.isEmpty()) {
return "";
if (instances.size() < 2) { // 1st index is always `Default`
throw new AccountPermissionException("First login detected, specify symbol");
}
return els.get(1).text();
return instances.get(1).text();
}
}
}

View File

@ -1,4 +1,10 @@
package io.github.wulkanowy.api.login;
public class LoginErrorException extends NotLoggedInErrorException {
import io.github.wulkanowy.api.NotLoggedInErrorException;
class LoginErrorException extends NotLoggedInErrorException {
LoginErrorException(String message) {
super(message);
}
}

View File

@ -1,4 +0,0 @@
package io.github.wulkanowy.api.login;
public class NotLoggedInErrorException extends Exception {
}

View File

@ -1,4 +0,0 @@
package io.github.wulkanowy.api.login;
public class VulcanOfflineException extends Exception {
}

View File

@ -1,4 +1,10 @@
package io.github.wulkanowy.api.messages;
class BadRequestException extends Exception {
import io.github.wulkanowy.api.VulcanException;
class BadRequestException extends VulcanException {
BadRequestException(String message) {
super(message);
}
}

View File

@ -7,7 +7,8 @@ import java.io.IOException;
import java.util.List;
import io.github.wulkanowy.api.Client;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.api.NotLoggedInErrorException;
import io.github.wulkanowy.api.VulcanException;
public class Messages {
@ -37,19 +38,19 @@ public class Messages {
this.client = client;
}
public List<Message> getReceived() throws IOException, NotLoggedInErrorException, BadRequestException {
public List<Message> getReceived() throws IOException, VulcanException {
return getMessages(RECEIVED_URL);
}
public List<Message> getSent() throws IOException, NotLoggedInErrorException, BadRequestException {
public List<Message> getSent() throws IOException, VulcanException {
return getMessages(SENT_URL);
}
public List<Message> getDeleted() throws IOException, NotLoggedInErrorException, BadRequestException {
public List<Message> getDeleted() throws IOException, VulcanException {
return getMessages(DELETED_URL);
}
private List<Message> getMessages(String url) throws IOException, NotLoggedInErrorException, BadRequestException {
private List<Message> getMessages(String url) throws IOException, VulcanException {
String res = client.getJsonStringByUrl(url);
List<Message> messages;
@ -58,16 +59,16 @@ public class Messages {
messages = new Gson().fromJson(res, MessagesContainer.class).data;
} catch (JsonParseException e) {
if (res.contains(ERROR_TITLE)) {
throw new BadRequestException();
throw new BadRequestException(ERROR_TITLE);
}
throw new NotLoggedInErrorException();
throw new NotLoggedInErrorException("You are probably not logged in");
}
return messages;
}
public Message getMessage(int id, int folder) throws IOException, BadRequestException, NotLoggedInErrorException {
public Message getMessage(int id, int folder) throws IOException, VulcanException {
String res = client.postJsonStringByUrl(MESSAGE_URL, new String[][]{
{"idWiadomosc", String.valueOf(id)},
{"Folder", String.valueOf(folder)}
@ -79,10 +80,10 @@ public class Messages {
message = new Gson().fromJson(res, MessageContainer.class).data;
} catch (JsonParseException e) {
if (res.contains(ERROR_TITLE)) {
throw new BadRequestException();
throw new BadRequestException(ERROR_TITLE);
}
throw new NotLoggedInErrorException();
throw new NotLoggedInErrorException("You are probably not logged in. Force login");
}
return message;

View File

@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class AchievementsList {
@ -21,7 +22,7 @@ public class AchievementsList {
this.snp = snp;
}
public List<String> getAllAchievements() throws IOException {
public List<String> getAllAchievements() throws IOException, VulcanException {
Element pageFragment = snp.getSnPPageDocument(NOTES_PAGE_URL)
.select(".mainContainer > div").get(1);
Elements items = pageFragment.select("article");

View File

@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class NotesList {
@ -21,7 +22,7 @@ public class NotesList {
this.snp = snp;
}
public List<Note> getAllNotes() throws IOException {
public List<Note> getAllNotes() throws IOException, VulcanException {
Element pageFragment = snp.getSnPPageDocument(NOTES_PAGE_URL)
.select(".mainContainer > div").get(0);
Elements items = pageFragment.select("article");

View File

@ -5,6 +5,7 @@ import org.jsoup.nodes.Element;
import java.io.IOException;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class SchoolInfo {
@ -16,7 +17,7 @@ public class SchoolInfo {
this.snp = snp;
}
public SchoolData getSchoolData() throws IOException {
public SchoolData getSchoolData() throws IOException, VulcanException {
Element e = snp.getSnPPageDocument(SCHOOL_PAGE_URL)
.select(".mainContainer > article").get(0);

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class TeachersInfo {
@ -20,7 +21,7 @@ public class TeachersInfo {
this.snp = snp;
}
public TeachersData getTeachersData() throws IOException {
public TeachersData getTeachersData() throws IOException, VulcanException {
Document doc = snp.getSnPPageDocument(SCHOOL_PAGE_URL);
Elements rows = doc.select(".mainContainer > table tbody tr");
String description = doc.select(".mainContainer > p").first().text();

View File

@ -13,7 +13,7 @@ import java.util.List;
import java.util.Locale;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.generic.Day;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.generic.Lesson;
import io.github.wulkanowy.api.generic.Week;
@ -27,25 +27,25 @@ public class Timetable {
this.snp = snp;
}
public Week<Day> getWeekTable() throws IOException, ParseException {
public Week<TimetableDay> getWeekTable() throws IOException, ParseException, VulcanException {
return getWeekTable("");
}
public Week<Day> getWeekTable(final String tick) throws IOException, ParseException {
public Week<TimetableDay> getWeekTable(final String tick) throws IOException, ParseException, VulcanException {
Element table = snp.getSnPPageDocument(TIMETABLE_PAGE_URL + tick)
.select(".mainContainer .presentData").first();
List<Day> days = getDays(table.select("thead th"));
List<TimetableDay> days = getDays(table.select("thead th"));
setLessonToDays(table, days);
return new Week<Day>()
return new Week<TimetableDay>()
.setStartDayDate(days.get(0).getDate())
.setDays(days);
}
private List<Day> getDays(Elements tableHeaderCells) throws ParseException {
List<Day> days = new ArrayList<>();
private List<TimetableDay> getDays(Elements tableHeaderCells) throws ParseException {
List<TimetableDay> days = new ArrayList<>();
for (int i = 2; i < 7; i++) {
String[] dayHeaderCell = tableHeaderCells.get(i).html().split("<br>");
@ -54,7 +54,7 @@ public class Timetable {
Date d = sdf.parse(dayHeaderCell[1].trim());
sdf.applyPattern("yyyy-MM-dd");
Day day = new Day();
TimetableDay day = new TimetableDay();
day.setDayName(dayHeaderCell[0]);
day.setDate(sdf.format(d));
@ -69,7 +69,7 @@ public class Timetable {
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")) {
Elements hours = row.select("td");
@ -98,7 +98,14 @@ public class Timetable {
addLessonInfoFromElement(lesson, e.first());
break;
case 2:
addLessonInfoFromElement(lesson, e.last());
Element span = e.last().select("span").first();
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;
case 3:
addLessonInfoFromElement(lesson, e.get(1));
@ -164,7 +171,8 @@ public class Timetable {
lesson.setRoom(spans.get(5).text());
lesson.setMovedOrCanceled(false);
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() + ")");
} else if (9 == spans.size()) {
String[] subjectAndGroupInfo = getLessonAndGroupInfoFromSpan(spans.get(4));
@ -175,13 +183,15 @@ public class Timetable {
lesson.setMovedOrCanceled(false);
lesson.setNewMovedInOrChanged(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] + ")");
} else if (4 <= spans.size()) {
lesson.setSubject(spans.get(0).text());
lesson.setTeacher(spans.get(1).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()));
}
}
@ -209,7 +219,8 @@ public class Timetable {
return new String[]{
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

@ -6,6 +6,7 @@ import org.jsoup.nodes.Element;
import java.io.IOException;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class BasicInformation {
@ -21,7 +22,7 @@ public class BasicInformation {
this.snp = snp;
}
public Document getStudentDataPageDocument() throws IOException {
public Document getStudentDataPageDocument() throws IOException, VulcanException {
if (null == studentDataPageDocument) {
studentDataPageDocument = snp.getSnPPageDocument(STUDENT_DATA_PAGE_URL);
}
@ -29,7 +30,7 @@ public class BasicInformation {
return studentDataPageDocument;
}
public PersonalData getPersonalData() throws IOException {
public PersonalData getPersonalData() throws IOException, VulcanException {
Element e = getStudentDataPageDocument().select(CONTENT_QUERY).get(0);
String name = snp.getRowDataChildValue(e, 1);
@ -48,7 +49,7 @@ public class BasicInformation {
.setParentsNames(snp.getRowDataChildValue(e, 7));
}
public AddressData getAddressData() throws IOException {
public AddressData getAddressData() throws IOException, VulcanException {
Element e = getStudentDataPageDocument().select(CONTENT_QUERY).get(1);
return new AddressData()
@ -58,7 +59,7 @@ public class BasicInformation {
}
public ContactDetails getContactDetails() throws IOException {
public ContactDetails getContactDetails() throws IOException, VulcanException {
Element e = getStudentDataPageDocument().select(CONTENT_QUERY).get(2);
return new ContactDetails()

View File

@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException;
public class FamilyInformation {
@ -19,7 +20,7 @@ public class FamilyInformation {
this.snp = snp;
}
public List<FamilyMember> getFamilyMembers() throws IOException {
public List<FamilyMember> getFamilyMembers() throws IOException, VulcanException {
Elements membersElements = snp.getSnPPageDocument(STUDENT_DATA_PAGE_URL)
.select(".mainContainer > article:nth-of-type(n+4)");

View File

@ -0,0 +1,63 @@
package io.github.wulkanowy.api;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Assert;
import org.junit.Test;
public class ClientTest {
private String getFixtureAsString(String fixtureFileName) {
return FixtureHelper.getAsString(getClass().getResourceAsStream(fixtureFileName));
}
@Test
public void setFullEndpointInfoTest() throws Exception {
Client client = new Client("http://fakelog.net\\\\admin", "pass", "Default");
Assert.assertEquals("fakelog.net", client.getHost());
Assert.assertEquals("Default", client.getSymbol());
}
@Test
public void checkForNoErrorsTest() throws Exception {
Client client = new Client("", "", "");
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-success.html"));
Assert.assertEquals(doc, client.checkForErrors(doc));
}
@Test(expected = VulcanOfflineException.class)
public void checkForErrorsOffline() throws Exception {
Client client = new Client("", "", "");
Document doc = Jsoup.parse(getFixtureAsString("login/PrzerwaTechniczna.html"));
client.checkForErrors(doc);
}
@Test(expected = NotLoggedInErrorException.class)
public void checkForErrors() throws Exception {
Client client = new Client("", "", "");
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-notLoggedIn.html"));
client.checkForErrors(doc);
}
@Test
public void getFilledUrlTest() throws Exception {
Client client = new Client("http://fakelog.cf\\\\admin", "", "symbol123");
Assert.assertEquals("http://uonetplus.fakelog.cf/symbol123/LoginEndpoint.aspx",
client.getFilledUrl("{schema}://uonetplus.{host}/{symbol}/LoginEndpoint.aspx"));
}
@Test
public void getSymbolTest() throws Exception {
Client client = new Client("", "", "symbol4321");
Assert.assertEquals("symbol4321", client.getSymbol());
}
}

View File

@ -7,11 +7,10 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
public class StudentAndParentTest {
private Client client;
@ -24,18 +23,21 @@ public class StudentAndParentTest {
client = Mockito.mock(Client.class);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(gradesPageDocument);
Mockito.when(client.getPageByUrl(
Mockito.anyString(),
Mockito.anyBoolean(), Mockito.anyMap())).thenReturn(gradesPageDocument);
}
@Test
public void snpTest() throws Exception {
StudentAndParent snp = new StudentAndParent(client, "id123");
Assert.assertEquals("id123", snp.getId());
public void snpTest() {
StudentAndParent snp = new StudentAndParent(client, "id123", null, null);
Assert.assertEquals("id123", snp.getSchoolID());
}
@Test
public void getSnpPageUrlWithIdTest() throws Exception {
Assert.assertEquals("{schema}://uonetplus-opiekun.{host}/{symbol}/123456/",
(new StudentAndParent(client, "123456")).getSnpHomePageUrl());
(new StudentAndParent(client, "123456", null, null)).getSnpHomePageUrl());
}
@Test
@ -45,7 +47,7 @@ public class StudentAndParentTest {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(startPageDocument);
StudentAndParent snp = new StudentAndParent(client);
StudentAndParent snp = new StudentAndParent(client, null, null, null);
Assert.assertEquals("https://uonetplus-opiekun.vulcan.net.pl/symbol/534213/Start/Index/",
snp.getSnpHomePageUrl());
@ -58,7 +60,7 @@ public class StudentAndParentTest {
);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(wrongPageDocument);
StudentAndParent snp = new StudentAndParent(client);
StudentAndParent snp = new StudentAndParent(client, null, null, null);
snp.getSnpHomePageUrl();
}
@ -66,7 +68,7 @@ public class StudentAndParentTest {
@Test
public void getExtractedIDStandardTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("123456", snp.getExtractedIdFromUrl("https://uonetplus-opiekun"
+ ".vulcan.net.pl/powiat/123456/Start/Index/"));
}
@ -74,7 +76,7 @@ public class StudentAndParentTest {
@Test
public void getExtractedIDDemoTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("demo12345",
snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
}
@ -82,44 +84,73 @@ public class StudentAndParentTest {
@Test(expected = NotLoggedInErrorException.class)
public void getExtractedIDNotLoggedTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
Assert.assertEquals("123",
snp.getExtractedIdFromUrl("https://uonetplus.vulcan.net.pl/powiat/"));
}
@Test
public void getSemestersTest() throws Exception {
SnP snp = new StudentAndParent(client, "123456");
SnP snp = new StudentAndParent(client, "123456", null, null);
List<Semester> semesters = snp.getSemesters();
Assert.assertEquals(2, semesters.size());
Assert.assertEquals("1", semesters.get(0).getId());
Assert.assertEquals("1234", semesters.get(0).getNumber());
Assert.assertEquals("1", semesters.get(0).getName());
Assert.assertEquals("1234", semesters.get(0).getId());
Assert.assertFalse(semesters.get(0).isCurrent());
Assert.assertEquals("2", semesters.get(1).getId());
Assert.assertEquals("1235", semesters.get(1).getNumber());
Assert.assertEquals("2", semesters.get(1).getName());
Assert.assertEquals("1235", semesters.get(1).getId());
Assert.assertTrue(semesters.get(1).isCurrent());
}
@Test
public void getCurrentSemesterTest() throws Exception {
public void getCurrentSemesterTest() {
List<Semester> semesters = new ArrayList<>();
semesters.add(new Semester().setNumber("1500100900").setId("1").setCurrent(false));
semesters.add(new Semester().setNumber("1500100901").setId("2").setCurrent(true));
semesters.add(new Semester().setName("1500100900").setId("1").setCurrent(false));
semesters.add(new Semester().setName("1500100901").setId("2").setCurrent(true));
SnP snp = new StudentAndParent(client, "");
Assert.assertTrue(snp.getCurrentSemester(semesters).isCurrent());
Assert.assertEquals("2", snp.getCurrentSemester(semesters).getId());
Assert.assertEquals("1500100901", snp.getCurrentSemester(semesters).getNumber());
SnP snp = new StudentAndParent(client, "", null, null);
Semester semester = snp.getCurrent(semesters);
Assert.assertTrue(semester.isCurrent());
Assert.assertEquals("2", semester.getId());
Assert.assertEquals("1500100901", semester.getName());
}
@Test
public void getCurrentSemesterFromEmptyTest() throws Exception {
SnP snp = new StudentAndParent(client, "");
public void getCurrentSemesterFromEmptyTest() {
SnP snp = new StudentAndParent(client, "", null, null);
List<Semester> semesters = new ArrayList<>();
Assert.assertNull(snp.getCurrentSemester(semesters));
Assert.assertNull(snp.getCurrent(semesters));
}
@Test
public void getDiariesAndStudentTest() throws IOException, VulcanException {
Document snpHome = Jsoup.parse(FixtureHelper.getAsString(
getClass().getResourceAsStream("StudentAndParent.html")));
client = Mockito.mock(Client.class);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(snpHome);
SnP snp = new StudentAndParent(client, "", null, null);
snp.setUp();
Assert.assertEquals("3Ti 2017", snp.getDiaries().get(0).getName());
Assert.assertEquals("2Ti 2016", snp.getDiaries().get(1).getName());
Assert.assertEquals("1Ti 2015", snp.getDiaries().get(2).getName());
Assert.assertEquals("1300", snp.getDiaries().get(0).getId());
Assert.assertEquals("1200", snp.getDiaries().get(1).getId());
Assert.assertEquals("1100", snp.getDiaries().get(2).getId());
Assert.assertTrue(snp.getDiaries().get(0).isCurrent());
Assert.assertFalse(snp.getDiaries().get(1).isCurrent());
Assert.assertFalse(snp.getDiaries().get(2).isCurrent());
Assert.assertEquals("Jan Kowal", snp.getStudents().get(0).getName());
Assert.assertEquals("100", snp.getStudents().get(0).getId());
}
}

View File

@ -16,7 +16,7 @@ public abstract class StudentAndParentTestCase {
Mockito.when(snp.getSnPPageDocument(Mockito.anyString()))
.thenReturn(tablePageDocument);
Mockito.when(snp.getSemesters(Mockito.any(Document.class))).thenCallRealMethod();
Mockito.when(snp.getCurrentSemester(Mockito.<Semester>anyList()))
Mockito.when(snp.getCurrent(Mockito.<Semester>anyList()))
.thenCallRealMethod();
Mockito.when(snp.getRowDataChildValue(Mockito.any(Element.class),
Mockito.anyInt())).thenCallRealMethod();

View File

@ -1,86 +1,31 @@
package io.github.wulkanowy.api;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.HashMap;
import java.util.Map;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
public class VulcanTest {
private Vulcan vulcan;
@Test(expected = NotLoggedInErrorException.class)
public void getClientWithoutLoginTest() throws Exception {
Vulcan vulcan = new Vulcan();
@Before
public void setUp() throws Exception {
vulcan = new Vulcan();
vulcan.setClient(Mockito.mock(Client.class));
vulcan.setLogin(Mockito.mock(Login.class));
vulcan.getClient();
}
@Test
public void setFullEndpointInfoTest() throws Exception {
vulcan.login("http://fakelog.net\\\\admin", "pass", "Default", "123");
public void getClientTest() throws Exception {
Vulcan vulcan = new Vulcan();
vulcan.setCredentials("email", "password", "symbol", null, null, null);
Assert.assertEquals("http", vulcan.getProtocolSchema());
Assert.assertEquals("fakelog.net", vulcan.getLogHost());
Assert.assertEquals("admin", vulcan.getEmail());
Assert.assertThat(vulcan.getClient(), CoreMatchers.instanceOf(Client.class));
}
@Test
public void getClientTwiceTest() throws Exception {
Vulcan vulcan = new Vulcan();
Assert.assertTrue(vulcan.getClient().equals(vulcan.getClient()));
}
vulcan.setCredentials("email", "password", "symbol", null, null, null);
@Test
public void getLoginTwiceTest() throws Exception {
Vulcan vulcan = new Vulcan();
Assert.assertTrue(vulcan.getLogin().equals(vulcan.getLogin()));
}
@Test(expected = NotLoggedInErrorException.class)
public void getStudentAndParentNotLoggedInTest() throws Exception {
vulcan.getStudentAndParent();
}
@Test
public void getStudentAndParentTwiceTest() throws Exception {
Client client = Mockito.mock(Client.class);
Map<String, String> cookies = new HashMap<>();
cookies.put("test", "test");
Mockito.when(client.getCookies()).thenReturn(cookies);
SnP snp = Mockito.mock(StudentAndParent.class);
Mockito.doNothing().when(snp).storeContextCookies();
Vulcan vulcan = Mockito.mock(Vulcan.class);
Mockito.when(vulcan.getClient()).thenReturn(client);
Mockito.when(vulcan.getStudentAndParent()).thenCallRealMethod();
Mockito.when(vulcan.createSnp(Mockito.any(Client.class), Mockito.any())).thenReturn(snp);
vulcan.getStudentAndParent();
vulcan.getStudentAndParent();
}
@Test
public void createSnPTest() throws Exception {
vulcan.login("wulkanowy@wulkanowy.io", "wulkanowy123", "wulkan");
SnP snp1 = vulcan.createSnp(Mockito.mock(Client.class), null);
Assert.assertEquals(null, snp1.getId());
SnP snp2 = vulcan.createSnp(Mockito.mock(Client.class), "wulkan");
Assert.assertEquals("wulkan", snp2.getId());
}
@Test(expected = NotLoggedInErrorException.class)
public void getAttendanceExceptionText() throws Exception {
vulcan.getAttendanceTable();
Assert.assertEquals(vulcan.getClient(), vulcan.getClient());
}
}

View File

@ -20,8 +20,8 @@ public class AttendanceTableTest extends StudentAndParentTestCase {
@Test
public void getWeekStartByDate() throws Exception {
Assert.assertEquals("31.08.2015", excellent.getWeekTable().getStartDayDate());
Assert.assertEquals("05.09.2016", full.getWeekTable().getStartDayDate());
Assert.assertEquals("2015-08-31", excellent.getWeekTable().getStartDayDate());
Assert.assertEquals("2016-09-05", full.getWeekTable().getStartDayDate());
}
@Test
@ -38,13 +38,13 @@ public class AttendanceTableTest extends StudentAndParentTestCase {
@Test
public void getDayDate() throws Exception {
Assert.assertEquals("31.08.2015", excellent.getWeekTable().getDay(0).getDate());
Assert.assertEquals("02.09.2015", excellent.getWeekTable().getDay(2).getDate());
Assert.assertEquals("04.09.2015", excellent.getWeekTable().getDay(4).getDate());
Assert.assertEquals("2015-08-31", excellent.getWeekTable().getDay(0).getDate());
Assert.assertEquals("2015-09-02", excellent.getWeekTable().getDay(2).getDate());
Assert.assertEquals("2015-09-04", excellent.getWeekTable().getDay(4).getDate());
Assert.assertEquals("05.09.2016", full.getWeekTable().getDay(0).getDate());
Assert.assertEquals("07.09.2016", full.getWeekTable().getDay(2).getDate());
Assert.assertEquals("09.09.2016", full.getWeekTable().getDay(4).getDate());
Assert.assertEquals("2016-09-05", full.getWeekTable().getDay(0).getDate());
Assert.assertEquals("2016-09-07", full.getWeekTable().getDay(2).getDate());
Assert.assertEquals("2016-09-09", full.getWeekTable().getDay(4).getDate());
}
@Test

View File

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

View File

@ -19,7 +19,7 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test
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
@ -60,6 +60,7 @@ public class GradesListTest extends StudentAndParentTestCase {
Assert.assertEquals("BW3", list.get(3).getSymbol());
Assert.assertEquals("STR", list.get(4).getSymbol());
Assert.assertEquals("K", list.get(5).getSymbol());
Assert.assertEquals("+Odp", list.get(6).getSymbol());
}
@Test
@ -70,6 +71,7 @@ public class GradesListTest extends StudentAndParentTestCase {
Assert.assertEquals("Writing", list.get(3).getDescription());
Assert.assertEquals("", list.get(4).getDescription());
Assert.assertEquals("Kordian", list.get(5).getDescription());
Assert.assertEquals("Kordian", list.get(6).getDescription());
}
@Test
@ -101,14 +103,4 @@ public class GradesListTest extends StudentAndParentTestCase {
Assert.assertEquals("Klaudia Dziedzic", list.get(4).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

@ -1,6 +1,5 @@
package io.github.wulkanowy.api.login;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Assert;
@ -12,93 +11,115 @@ import io.github.wulkanowy.api.FixtureHelper;
public class LoginTest {
private Document getFixtureAsDocument(String fixtureFileName) {
return Jsoup.parse(getFixtureAsString(fixtureFileName));
}
private String getFixtureAsString(String fixtureFileName) {
return FixtureHelper.getAsString(getClass().getResourceAsStream(fixtureFileName));
}
private Client getClient(String fixtureFileName) throws Exception {
Document doc = Jsoup.parse(getFixtureAsString(fixtureFileName));
Document doc = getFixtureAsDocument(fixtureFileName);
Client client = Mockito.mock(Client.class);
Mockito.when(client.postPageByUrl(Mockito.anyString(), Mockito.any(String[][].class))).thenReturn(doc);
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(doc);
return client;
}
@Test
public void loginTest() throws Exception {
Login login = new Login(getClient("Logowanie-success.html"));
Client client = getClient("Logowanie-success.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.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);
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
}
@Test(expected = BadCredentialsException.class)
public void sendWrongCredentialsTest() throws Exception {
Login login = new Login(getClient("Logowanie-error.html"));
Client client = getClient("Logowanie-error.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html")); // -error.html because it html with form used by
Login login = new Login(client);
login.sendCredentials("a@a", "pswd", "d123");
login.sendCredentials("a@a", "pswd");
}
@Test
public void sendCredentialsCertificateTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html"));
Client client = getClient("Logowanie-certyfikat.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html")); // -error.html because it html with form used by
Login login = new Login(client);
Assert.assertEquals(
getFixtureAsString("cert.xml").replaceAll("\\s+",""),
login.sendCredentials("a@a", "passwd", "d123").replaceAll("\\s+","")
getFixtureAsString("cert-stock.xml").replaceAll("\\s+", ""),
login.sendCredentials("a@a", "passwd")
.select("input[name=wresult]")
.attr("value")
.replaceAll("\\s+", "")
);
}
@Test
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",
login.sendCertificate("", "wulkanowyschool321"));
Assert.assertEquals("wulkanowyschool321", login.sendCertificate(
getFixtureAsDocument("Logowanie-certyfikat.html"), "wulkanowyschool321"));
}
@Test
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",
login.sendCertificate(getFixtureAsString("cert.xml"), "Default"));
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default"));
}
@Test(expected = AccountPermissionException.class)
public void sendCertificateAccountPermissionTest() throws Exception {
Login login = new Login(getClient("Logowanie-brak-dostepu.html"));
Client client = getClient("Logowanie-brak-dostepu.html");
login.sendCertificate(getFixtureAsString("cert.xml"), "demo123");
Login login = new Login(client);
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
}
@Test(expected = LoginErrorException.class)
public void sendCertificateLoginErrorTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document
login.sendCertificate(getFixtureAsString("cert.xml"), "demo123");
}
@Test(expected = VulcanOfflineException.class)
public void sendCertificateVulcanOfflineTest() throws Exception {
Login login = new Login(getClient("PrzerwaTechniczna.html"));
login.sendCertificate(getFixtureAsString("cert.xml"), "demo123");
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
}
@Test
public void findSymbolInCertificateTest() throws Exception {
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));
}
@Test
public void findSymbolInInvalidCertificateTest() throws Exception {
@Test(expected = AccountPermissionException.class)
public void findSymbolInCertificateWithoutSecondInstanceTest() throws Exception {
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

@ -8,7 +8,7 @@ import java.util.List;
import io.github.wulkanowy.api.Client;
import io.github.wulkanowy.api.FixtureHelper;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.api.NotLoggedInErrorException;
public class MessagesTest {

View File

@ -110,6 +110,7 @@ public class TimetableTest extends StudentAndParentTestCase {
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("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());
}
@ -122,6 +123,7 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("Nowak Jadwiga", full.getWeekTable().getDay(2).getLesson(0).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("", full.getWeekTable().getDay(4).getLesson(1).getTeacher());
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getTeacher());
}
@ -148,7 +150,11 @@ public class TimetableTest extends StudentAndParentTestCase {
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("", 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("", full.getWeekTable().getDay(4).getLesson(1).getDescription());
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getDescription());
}
@ -237,6 +243,8 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(2).isNewMovedInOrChanged());
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(3).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());
}
}

View File

@ -15,7 +15,8 @@
<option selected="selected" value="1235">2</option>
</select>
</div>
</main>
</div>
</main>
<footer>wersja: 17.05.0000.24042</footer>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Strona gł&#243;wna</title>
</head>
<body>
<ul id="idSection">
<li>
<label for="uczenDropDownList">Uczeń:</label>
<select id="uczenDropDownList" name="uczenDropDownList">
<option selected="selected"
value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Uczen/UczenOnChange?&amp;id=100">
Jan Kowal
</option>
</select>
</li>
<li>
<label for="dziennikDropDownList">Dziennik:</label>
<select id="dziennikDropDownList" name="dziennikDropDownList">
<option selected="selected"
value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1300">
3Ti 2017
</option>
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1200">
2Ti 2016
</option>
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&amp;id=1100">
1Ti 2015
</option>
</select>
</li>
</ul>
<footer>wersja: 17.09.0008.26553</footer>
</body>
</html>

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>Amelia Stępień</td>
</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>
</table>
</main>

View File

@ -3,10 +3,10 @@
<title>Working...</title>
</head>
<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="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="wctx" value="https://fake-log.com/Default/LoginEndpoint.aspx">
<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://fakelog.cf/Default/LoginEndpoint.aspx">
<noscript>
<p>Script is disabled. Click Submit to continue.</p>
<input type="submit" value="Submit">

View File

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

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dziennik UONET+</title>
</head>
<body>
<div id="MainPage_InfoPage">
<div class="startScreen">
<div class="topBar">
<div class="loginBox">
<div>
<a href="/LoginEndpoint.aspx" class="loginButton"></a>
<a href="/LoginEndpoint.aspx" class="loginButton">Zaloguj się</a>
</div>
</div>
</div>
<div class="bottomBar"><span>Uonet+ wersja 17.09.0007.26300</span></div>
</div>
</div>
</body>
</html>

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:RequestSecurityTokenResponse Context="https://uonetplus.fake-log.com/Default/LoginEndpoint.aspx">
<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.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>demo12345</saml:AttributeValue>
<saml:AttributeValue>incorrect value</saml:AttributeValue>

View File

@ -3,6 +3,40 @@
<head>
<meta charset="utf-8">
<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>
<body>
<main class="mainContainer">
@ -82,13 +116,6 @@
</div>
</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>
<span class="x-treelabel-ppl x-treelabel-zas">Wychowanie fizyczne [zaw2]</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-rlz">(przeniesiona z lekcji 7, 01.12.2017)</span>
</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>
<div>
@ -118,7 +152,18 @@
<span class="x-treelabel-rlz">(zastępstwo)</span>
</div>
</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>
<td>2</td>
@ -165,7 +210,20 @@
<span></span>
</div>
</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>
<td>3</td>
@ -214,7 +272,17 @@
<span></span>
</div>
</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>
<td>4</td>

View File

@ -2,11 +2,14 @@ buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
maven { url 'https://maven.fabric.io/public' }
google()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
classpath 'io.fabric.tools:gradle:1.25.1'
classpath "org.greenrobot:greendao-gradle-plugin:$greenDaoGradle"
classpath "io.fabric.tools:gradle:$fabricGradle"
classpath "com.google.gms:oss-licenses:0.9.2"
classpath 'com.github.triplet.gradle:play-publisher:1.2.0'
}
}
@ -19,30 +22,53 @@ apply plugin: 'org.greenrobot.greendao'
apply plugin: 'io.fabric'
apply from: '../jacoco.gradle'
apply from: '../android-sonarqube.gradle'
apply plugin: 'com.google.gms.oss.licenses.plugin'
apply plugin: 'com.github.triplet.play'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 26
buildToolsVersion '27.0.3'
playAccountConfigs {
defaultAccountConfig {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL")
pk12File = file('key.p12')
}
}
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15
targetSdkVersion 27
versionCode 2
versionName "0.1.1"
targetSdkVersion 26
versionCode 9
versionName "0.4.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
playAccountConfig = playAccountConfigs.defaultAccountConfig
manifestPlaceholders = [
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 {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
testCoverageEnabled = true
ext.enableCrashlytics = false
}
@ -59,48 +85,56 @@ android {
}
}
play {
track = 'alpha'
uploadImages = true
}
greendao {
schemaVersion 20
schemaVersion 26
generateTests = true
}
configurations.all {
resolutionStrategy.force "com.android.support:support-annotations:$supportVersion"
}
dependencies {
implementation project(':api')
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support:support-v4:27.1.0'
implementation 'com.android.support:recyclerview-v7:27.1.0'
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'com.android.support:customtabs:27.1.0'
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
implementation 'org.apache.commons:commons-lang3:3.7'
implementation 'eu.davidea:flexible-adapter:5.0.0-rc4'
implementation 'eu.davidea:flexible-adapter-ui:1.0.0-b1'
implementation 'org.apache.commons:commons-collections4:4.1'
implementation 'org.greenrobot:greendao:3.2.2'
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'joda-time:joda-time:2.9.9'
implementation 'com.google.dagger:dagger-android:2.14.1'
implementation 'com.google.dagger:dagger-android-support:2.14.1'
implementation 'com.aurelhubert:ahbottomnavigation:2.1.0'
implementation "com.android.support:support-v4:$supportVersion"
implementation "com.android.support:design:$supportVersion"
implementation "com.android.support:cardview-v7:$supportVersion"
implementation "com.android.support:customtabs:$supportVersion"
implementation "com.android.support:preference-v14:$supportVersion"
implementation "com.firebase:firebase-jobdispatcher:$firebaseJob"
implementation "org.apache.commons:commons-lang3:$apacheLang"
implementation "org.apache.commons:commons-collections4:$apacheCollections"
implementation "eu.davidea:flexible-adapter:$flexibleAdapter"
implementation "eu.davidea:flexible-adapter-ui:$flexibleUi"
implementation "org.greenrobot:greendao:$greenDao"
implementation "com.jakewharton:butterknife:$butterknife"
implementation "com.google.dagger:dagger-android-support:$dagger2"
implementation "com.aurelhubert:ahbottomnavigation:$ahbottom"
implementation "com.jakewharton.threetenabp:threetenabp:$threeTenABP"
implementation "com.google.android.gms:play-services-oss-licenses:$ossLicenses"
implementation('com.crashlytics.sdk.android:crashlytics:2.8.0@aar') {
implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsSdk@aar") {
transitive = true
}
implementation('com.crashlytics.sdk.android:answers:1.4.1@aar') {
implementation("com.crashlytics.sdk.android:answers:$crashlyticsAnswers@aar") {
transitive = true
}
annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger2"
annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife"
debugImplementation 'com.amitshekhar.android:debug-db:1.0.1'
debugImplementation 'net.zetetic:android-database-sqlcipher:3.5.9'
debugImplementation "com.amitshekhar.android:debug-db:$debugDb"
debugImplementation "net.zetetic:android-database-sqlcipher:$sqlcipher"
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.13.0'
testImplementation "junit:junit:$junit"
testImplementation "org.mockito:mockito-core:$mockito"
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'org.mockito:mockito-android:2.13.0'
androidTestImplementation "com.android.support.test:runner:$testRunner"
androidTestImplementation "org.mockito:mockito-android:$mockito"
}

BIN
app/key-encrypted.p12 Normal file

Binary file not shown.

View File

@ -0,0 +1,25 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class AttendanceLessonTest extends AbstractDaoTestLongPk<AttendanceLessonDao, AttendanceLesson> {
public AttendanceLessonTest() {
super(AttendanceLessonDao.class);
}
@Override
protected AttendanceLesson createEntity(Long key) {
AttendanceLesson entity = new AttendanceLesson();
entity.setId(key);
entity.setPresence(false);
entity.setAbsenceUnexcused(false);
entity.setAbsenceExcused(false);
entity.setUnexcusedLateness(false);
entity.setAbsenceForSchoolReasons(false);
entity.setExcusedLateness(false);
entity.setExemption(false);
return entity;
}
}

View File

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

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class DiaryTest extends AbstractDaoTestLongPk<DiaryDao, Diary> {
public DiaryTest() {
super(DiaryDao.class);
}
@Override
protected Diary createEntity(Long key) {
Diary entity = new Diary();
entity.setId(key);
entity.setCurrent(false);
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

@ -1,24 +0,0 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class LessonTest extends AbstractDaoTestLongPk<LessonDao, Lesson> {
public LessonTest() {
super(LessonDao.class);
}
@Override
protected Lesson createEntity(Long key) {
Lesson entity = new Lesson();
entity.setId(key);
entity.setIsEmpty(false);
entity.setIsDivisionIntoGroups(false);
entity.setIsPlanning(false);
entity.setIsRealized(false);
entity.setIsMovedOrCanceled(false);
entity.setIsNewMovedInOrChanged(false);
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

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class TimetableLessonTest extends AbstractDaoTestLongPk<TimetableLessonDao, TimetableLesson> {
public TimetableLessonTest() {
super(TimetableLessonDao.class);
}
@Override
protected TimetableLesson createEntity(Long key) {
TimetableLesson entity = new TimetableLesson();
entity.setId(key);
entity.setEmpty(false);
entity.setDivisionIntoGroups(false);
entity.setPlanning(false);
entity.setRealized(false);
entity.setMovedOrCanceled(false);
entity.setNewMovedInOrChanged(false);
return entity;
}
}

View File

@ -0,0 +1,3 @@
<resources>
<string name="app_name">Wulkanowy DEV</string>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<string name="app_name">Wulkanowy DEV</string>
</resources>

View File

@ -10,8 +10,7 @@
<application
android:name=".WulkanowyApp"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
@ -32,19 +31,40 @@
android:name=".ui.login.LoginActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_login"
android:theme="@style/WulkanowyTheme.LoginTheme"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.main.MainActivity"
android:configChanges="orientation|screenSize"
android:label="@string/activity_dashboard_text" />
android:label="@string/activity_dashboard_text"
android:launchMode="singleTop"
android:theme="@style/WulkanowyTheme" />
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
android:theme="@style/WulkanowyTheme.LoginTheme" />
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/WulkanowyTheme.LoginTheme" />
<service
android:name=".services.SyncJob"
android:name=".services.jobs.SyncJob"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</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
android:name="io.fabric.ApiKey"

View File

@ -4,6 +4,7 @@ import android.app.Application;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.core.CrashlyticsCore;
import com.jakewharton.threetenabp.AndroidThreeTen;
import org.greenrobot.greendao.query.QueryBuilder;
@ -16,6 +17,7 @@ import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.di.component.ApplicationComponent;
import io.github.wulkanowy.di.component.DaggerApplicationComponent;
import io.github.wulkanowy.di.modules.ApplicationModule;
import io.github.wulkanowy.utils.LogUtils;
public class WulkanowyApp extends Application {
@ -27,6 +29,8 @@ public class WulkanowyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
AndroidThreeTen.init(this);
applicationComponent = DaggerApplicationComponent
.builder()
.applicationModule(new ApplicationModule(this))
@ -37,6 +41,17 @@ public class WulkanowyApp extends Application {
enableDebugLog();
}
initializeFabric();
initializeUserSession();
}
private void initializeUserSession() {
if (repository.getSharedRepo().isUserLoggedIn()) {
try {
repository.getSyncRepo().initLastUser();
} catch (Exception e) {
LogUtils.error("An error occurred when the application was started", e);
}
}
}
private void enableDebugLog() {

View File

@ -1,143 +1,50 @@
package io.github.wulkanowy.data;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.api.login.VulcanOfflineException;
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.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.dao.DbContract;
import io.github.wulkanowy.data.db.resources.ResourcesContract;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.data.sync.SyncContract;
import io.github.wulkanowy.data.sync.login.LoginSyncContract;
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
public class Repository implements RepositoryContract {
private final SharedPrefContract sharedPref;
private final DbContract database;
private final ResourcesContract resources;
private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
private final LoginSyncContract loginSync;
private final TimetableSyncContract timetableSync;
private final SyncContract gradeSync;
private final SyncContract subjectSync;
private final SyncContract synchronization;
@Inject
Repository(SharedPrefContract sharedPref,
ResourcesContract resources,
DaoSession daoSession,
LoginSyncContract loginSync,
TimetableSyncContract timetableSync,
@SyncGrades SyncContract gradeSync,
@SyncSubjects SyncContract subjectSync) {
this.sharedPref = sharedPref;
Repository(DbContract database, ResourcesContract resources, SharedPrefContract sharedPref,
SyncContract synchronization) {
this.database = database;
this.resources = resources;
this.daoSession = daoSession;
this.loginSync = loginSync;
this.timetableSync = timetableSync;
this.gradeSync = gradeSync;
this.subjectSync = subjectSync;
this.sharedPref = sharedPref;
this.synchronization = synchronization;
}
@Override
public long getCurrentUserId() {
return sharedPref.getCurrentUserId();
public SharedPrefContract getSharedRepo() {
return sharedPref;
}
@Override
public String[] getSymbolsKeysArray() {
return resources.getSymbolsKeysArray();
public ResourcesContract getResRepo() {
return resources;
}
@Override
public String[] getSymbolsValuesArray() {
return resources.getSymbolsValuesArray();
public DbContract getDbRepo() {
return database;
}
@Override
public String getErrorLoginMessage(Exception e) {
return resources.getErrorLoginMessage(e);
}
@Override
public void loginUser(String email, String password, String symbol)
throws NotLoggedInErrorException, AccountPermissionException, IOException,
CryptoException, VulcanOfflineException, BadCredentialsException {
loginSync.loginUser(email, password, symbol);
}
@Override
public void loginCurrentUser() throws NotLoggedInErrorException, AccountPermissionException,
IOException, CryptoException, VulcanOfflineException, BadCredentialsException {
loginSync.loginCurrentUser();
}
@Override
public void syncGrades() throws NotLoggedInErrorException, IOException, ParseException {
gradeSync.sync();
}
@Override
public void syncSubjects() throws NotLoggedInErrorException, IOException, ParseException {
subjectSync.sync();
}
@Override
public void syncTimetable() throws NotLoggedInErrorException, IOException, ParseException {
timetableSync.syncTimetable();
}
@Override
public void syncTimetable(String date) throws NotLoggedInErrorException, IOException, ParseException {
timetableSync.syncTimetable(date);
}
@Override
public void syncAll() throws NotLoggedInErrorException, IOException, ParseException {
syncSubjects();
syncGrades();
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();
public SyncContract getSyncRepo() {
return synchronization;
}
}

View File

@ -1,34 +1,20 @@
package io.github.wulkanowy.data;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import javax.inject.Singleton;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
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.dao.DbContract;
import io.github.wulkanowy.data.db.resources.ResourcesContract;
import io.github.wulkanowy.data.sync.login.LoginSyncContract;
import io.github.wulkanowy.data.sync.timetable.TimetableSyncContract;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.data.sync.SyncContract;
@Singleton
public interface RepositoryContract extends ResourcesContract, LoginSyncContract,
TimetableSyncContract {
public interface RepositoryContract {
long getCurrentUserId();
SharedPrefContract getSharedRepo();
void syncGrades() throws NotLoggedInErrorException, IOException, ParseException;
ResourcesContract getResRepo();
void syncSubjects() throws NotLoggedInErrorException, IOException, ParseException;
DbContract getDbRepo();
void syncAll() throws NotLoggedInErrorException, IOException, ParseException;
Account getCurrentUser();
Week getWeek(String date);
List<Grade> getNewGrades();
SyncContract getSyncRepo();
}

View File

@ -0,0 +1,30 @@
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.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();
long getCurrentDiaryId();
long getSemesterId(int name);
long getCurrentSemesterId();
int getCurrentSemesterName();
}

View File

@ -1,19 +1,97 @@
package io.github.wulkanowy.data.db.dao;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.StandardDatabase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.api.Vulcan;
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.Migration26;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.di.annotations.DatabaseInfo;
import io.github.wulkanowy.utils.LogUtils;
@Singleton
public class DbHelper extends DaoMaster.DevOpenHelper {
public class DbHelper extends DaoMaster.OpenHelper {
private final SharedPrefContract sharedPref;
private final Vulcan vulcan;
@Inject
DbHelper(@ApplicationContext Context context, @DatabaseInfo String dbName) {
DbHelper(@ApplicationContext Context context, @DatabaseInfo String dbName,
SharedPrefContract sharedPref, Vulcan vulcan) {
super(context, dbName);
this.sharedPref = sharedPref;
this.vulcan = vulcan;
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
LogUtils.info("Cleaning user data oldVersion=" + oldVersion + " newVersion=" + newVersion);
Database database = new StandardDatabase(db);
recreateDatabase(database);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
List<Migration> migrations = getMigrations();
// Only run migrations past the old version
for (Migration migration : migrations) {
if (oldVersion < migration.getVersion()) {
try {
LogUtils.info("Applying migration to db schema v" + migration.getVersion() + "...");
migration.runMigration(db, sharedPref, vulcan);
LogUtils.info("Migration " + migration.getVersion() + " complete");
} catch (Exception e) {
e.printStackTrace();
recreateDatabase(db);
break;
}
}
}
}
private void recreateDatabase(Database db) {
LogUtils.info("Database is recreating...");
sharedPref.setCurrentUserId(0);
DaoMaster.dropAllTables(db, true);
onCreate(db);
}
private List<Migration> getMigrations() {
List<Migration> migrations = new ArrayList<>();
migrations.add(new Migration23());
migrations.add(new Migration26());
// Sorting just to be safe, in case other people add migrations in the wrong order.
Comparator<Migration> migrationComparator = new Comparator<Migration>() {
@Override
public int compare(Migration m1, Migration m2) {
return m1.getVersion().compareTo(m2.getVersion());
}
};
Collections.sort(migrations, migrationComparator);
return migrations;
}
public interface Migration {
Integer getVersion();
void runMigration(Database db, SharedPrefContract sharedPref, Vulcan vulcan) throws Exception;
}
}

View File

@ -0,0 +1,106 @@
package io.github.wulkanowy.data.db.dao;
import java.util.List;
import javax.inject.Inject;
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.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 long getCurrentSymbolId() {
return daoSession.getSymbolDao().queryBuilder().where(
SymbolDao.Properties.UserId.eq(sharedPref.getCurrentUserId())
).unique().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();
}
}

View File

@ -6,6 +6,7 @@ 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 org.greenrobot.greendao.annotation.Unique;
import java.util.List;
@ -18,29 +19,15 @@ public class Account {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "E-MAIL")
@Unique
@Property(nameInDb = "email")
private String email;
@Property(nameInDb = "PASSWORD")
@Property(nameInDb = "password")
private String password;
@Property(nameInDb = "SYMBOL")
private String symbol;
@Property(nameInDb = "SNPID")
private String snpId;
@ToMany(referencedJoinProperty = "userId")
private List<Subject> subjectList;
@ToMany(referencedJoinProperty = "userId")
private List<Grade> gradeList;
@ToMany(referencedJoinProperty = "userId")
private List<Day> dayList;
private List<Symbol> symbolList;
/**
* Used to resolve relations
@ -54,15 +41,11 @@ public class Account {
@Generated(hash = 335469827)
private transient AccountDao myDao;
@Generated(hash = 735765217)
public Account(Long id, String name, String email, String password, String symbol,
String snpId) {
@Generated(hash = 1104194311)
public Account(Long id, String email, String password) {
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.symbol = symbol;
this.snpId = snpId;
}
@Generated(hash = 882125521)
@ -70,25 +53,15 @@ public class Account {
}
public Long getId() {
return id;
return this.id;
}
public Account setId(Long id) {
public void setId(Long id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Account setName(String name) {
this.name = name;
return this;
}
public String getEmail() {
return email;
return this.email;
}
public Account setEmail(String email) {
@ -97,7 +70,7 @@ public class Account {
}
public String getPassword() {
return password;
return this.password;
}
public Account setPassword(String password) {
@ -105,82 +78,34 @@ public class Account {
return this;
}
public String getSymbol() {
return symbol;
}
public Account setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
public String getSnpId() {
return this.snpId;
}
public Account setSnpId(String snpId) {
this.snpId = snpId;
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 = 1800750450)
public List<Subject> getSubjectList() {
if (subjectList == null) {
@Generated(hash = 822972496)
public List<Symbol> getSymbolList() {
if (symbolList == 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);
SymbolDao targetDao = daoSession.getSymbolDao();
List<Symbol> symbolListNew = targetDao._queryAccount_SymbolList(id);
synchronized (this) {
if (subjectList == null) {
subjectList = subjectListNew;
if (symbolList == null) {
symbolList = symbolListNew;
}
}
}
return subjectList;
return symbolList;
}
/**
* 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;
@Generated(hash = 1716801695)
public synchronized void resetSymbolList() {
symbolList = null;
}
/**
@ -219,36 +144,6 @@ public class Account {
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 = 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;
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1812283172)
public void __setDaoSession(DaoSession daoSession) {

View File

@ -0,0 +1,254 @@
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 org.greenrobot.greendao.annotation.Transient;
import java.io.Serializable;
@Entity(
nameInDb = "AttendanceLessons",
active = true,
indexes = {@Index(value = "dayId,date,number", unique = true)}
)
public class AttendanceLesson implements Serializable {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "day_id")
private Long dayId;
@Property(nameInDb = "date")
private String date = "";
@Property(nameInDb = "number_of_lesson")
private int number = 0;
@Property(nameInDb = "subject")
private String subject = "";
@Property(nameInDb = "presence")
private boolean presence = false;
@Property(nameInDb = "absence_unexcused")
private boolean absenceUnexcused = false;
@Property(nameInDb = "absence_excused")
private boolean absenceExcused = false;
@Property(nameInDb = "unexcused_lateness")
private boolean unexcusedLateness = false;
@Property(nameInDb = "absence_for_school_reasons")
private boolean absenceForSchoolReasons = false;
@Property(nameInDb = "excused_lateness")
private boolean excusedLateness = false;
@Property(nameInDb = "exemption")
private boolean exemption = false;
@Transient
private String description = "";
private static final long serialVersionUID = 42L;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 1936953859)
private transient AttendanceLessonDao myDao;
@Generated(hash = 1741231228)
public AttendanceLesson(Long id, Long dayId, String date, int number,
String subject, boolean presence, boolean absenceUnexcused,
boolean absenceExcused, boolean unexcusedLateness,
boolean absenceForSchoolReasons, boolean excusedLateness,
boolean exemption) {
this.id = id;
this.dayId = dayId;
this.date = date;
this.number = number;
this.subject = subject;
this.presence = presence;
this.absenceUnexcused = absenceUnexcused;
this.absenceExcused = absenceExcused;
this.unexcusedLateness = unexcusedLateness;
this.absenceForSchoolReasons = absenceForSchoolReasons;
this.excusedLateness = excusedLateness;
this.exemption = exemption;
}
@Generated(hash = 921806575)
public AttendanceLesson() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDayId() {
return this.dayId;
}
public void setDayId(Long dayId) {
this.dayId = dayId;
}
public String getDate() {
return this.date;
}
public AttendanceLesson setDate(String date) {
this.date = date;
return this;
}
public int getNumber() {
return this.number;
}
public AttendanceLesson setNumber(int number) {
this.number = number;
return this;
}
public String getSubject() {
return this.subject;
}
public AttendanceLesson setSubject(String subject) {
this.subject = subject;
return this;
}
public boolean getPresence() {
return this.presence;
}
public AttendanceLesson setPresence(boolean presence) {
this.presence = presence;
return this;
}
public boolean getAbsenceUnexcused() {
return this.absenceUnexcused;
}
public AttendanceLesson setAbsenceUnexcused(boolean absenceUnexcused) {
this.absenceUnexcused = absenceUnexcused;
return this;
}
public boolean getAbsenceExcused() {
return this.absenceExcused;
}
public AttendanceLesson setAbsenceExcused(boolean absenceExcused) {
this.absenceExcused = absenceExcused;
return this;
}
public boolean getUnexcusedLateness() {
return this.unexcusedLateness;
}
public AttendanceLesson setUnexcusedLateness(boolean unexcusedLateness) {
this.unexcusedLateness = unexcusedLateness;
return this;
}
public boolean getAbsenceForSchoolReasons() {
return this.absenceForSchoolReasons;
}
public AttendanceLesson setAbsenceForSchoolReasons(boolean absenceForSchoolReasons) {
this.absenceForSchoolReasons = absenceForSchoolReasons;
return this;
}
public boolean getExcusedLateness() {
return this.excusedLateness;
}
public AttendanceLesson setExcusedLateness(boolean excusedLateness) {
this.excusedLateness = excusedLateness;
return this;
}
public boolean getExemption() {
return this.exemption;
}
public AttendanceLesson setExemption(boolean exemption) {
this.exemption = exemption;
return this;
}
public String getDescription() {
return description;
}
public AttendanceLesson setDescription(String description) {
this.description = description;
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 = 1157101112)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getAttendanceLessonDao() : null;
}
}

View File

@ -13,33 +13,36 @@ import java.util.List;
@Entity(
nameInDb = "Days",
active = true,
indexes ={@Index(value = "userId,weekId,date", unique = true)}
indexes = {@Index(value = "weekId,date", unique = true)}
)
public class Day {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "USER_ID")
private Long userId;
@Property(nameInDb = "WEEK_ID")
@Property(nameInDb = "week_id")
private Long weekId;
@Property(nameInDb = "DATE")
@Property(nameInDb = "date")
private String date = "";
@Property(nameInDb = "DAY_NAME")
@Property(nameInDb = "day_name")
private String dayName = "";
@Property(nameInDb = "IS_FREE_DAY")
private boolean isFreeDay = false;
@Property(nameInDb = "free_day")
private boolean freeDay = false;
@Property(nameInDb = "FREE_DAY_NAME")
@Property(nameInDb = "free_day_name")
private String freeDayName = "";
@ToMany(referencedJoinProperty = "dayId")
private List<Lesson> lessons;
private List<TimetableLesson> timetableLessons;
@ToMany(referencedJoinProperty = "dayId")
private List<AttendanceLesson> attendanceLessons;
@ToMany(referencedJoinProperty = "dayId")
private List<Exam> exams;
/**
* Used to resolve relations
@ -53,15 +56,14 @@ public class Day {
@Generated(hash = 312167767)
private transient DayDao myDao;
@Generated(hash = 723729681)
public Day(Long id, Long userId, Long weekId, String date, String dayName,
boolean isFreeDay, String freeDayName) {
@Generated(hash = 523139020)
public Day(Long id, Long weekId, String date, String dayName, boolean freeDay,
String freeDayName) {
this.id = id;
this.userId = userId;
this.weekId = weekId;
this.date = date;
this.dayName = dayName;
this.isFreeDay = isFreeDay;
this.freeDay = freeDay;
this.freeDayName = freeDayName;
}
@ -77,26 +79,16 @@ public class Day {
this.id = id;
}
public Long getUserId() {
return userId;
}
public Long getWeekId() {
return weekId;
return this.weekId;
}
public Day setWeekId(Long weekId) {
public void setWeekId(Long weekId) {
this.weekId = weekId;
return this;
}
public Day setUserId(Long userId) {
this.userId = userId;
return this;
}
public String getDate() {
return date;
return this.date;
}
public Day setDate(String date) {
@ -105,7 +97,7 @@ public class Day {
}
public String getDayName() {
return dayName;
return this.dayName;
}
public Day setDayName(String dayName) {
@ -113,17 +105,17 @@ public class Day {
return this;
}
public boolean isFreeDay() {
return isFreeDay;
public boolean getFreeDay() {
return this.freeDay;
}
public Day setFreeDay(boolean freeDay) {
isFreeDay = freeDay;
this.freeDay = freeDay;
return this;
}
public String getFreeDayName() {
return freeDayName;
return this.freeDayName;
}
public Day setFreeDayName(String freeDayName) {
@ -131,42 +123,66 @@ public class Day {
return this;
}
public boolean getIsFreeDay() {
return this.isFreeDay;
/**
* 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 = 218588195)
public List<TimetableLesson> getTimetableLessons() {
if (timetableLessons == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
TimetableLessonDao targetDao = daoSession.getTimetableLessonDao();
List<TimetableLesson> timetableLessonsNew = targetDao
._queryDay_TimetableLessons(id);
synchronized (this) {
if (timetableLessons == null) {
timetableLessons = timetableLessonsNew;
}
}
}
return timetableLessons;
}
public void setIsFreeDay(boolean isFreeDay) {
this.isFreeDay = isFreeDay;
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1687683740)
public synchronized void resetTimetableLessons() {
timetableLessons = 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 = 1552857303)
public List<Lesson> getLessons() {
if (lessons == null) {
@Generated(hash = 1166820581)
public List<AttendanceLesson> getAttendanceLessons() {
if (attendanceLessons == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
LessonDao targetDao = daoSession.getLessonDao();
List<Lesson> lessonsNew = targetDao._queryDay_Lessons(id);
AttendanceLessonDao targetDao = daoSession.getAttendanceLessonDao();
List<AttendanceLesson> attendanceLessonsNew = targetDao
._queryDay_AttendanceLessons(id);
synchronized (this) {
if (lessons == null) {
lessons = lessonsNew;
if (attendanceLessons == null) {
attendanceLessons = attendanceLessonsNew;
}
}
}
return lessons;
return attendanceLessons;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1769801440)
public synchronized void resetLessons() {
lessons = null;
@Generated(hash = 1343075564)
public synchronized void resetAttendanceLessons() {
attendanceLessons = null;
}
/**
@ -205,6 +221,36 @@ public class Day {
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 = 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;
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1409317752)
public void __setDaoSession(DaoSession daoSession) {

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.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(
nameInDb = "Diaries",
active = true
)
public class Diary {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "student_id")
private Long studentId;
@Property(nameInDb = "current")
private boolean current;
@Property(nameInDb = "name")
private String name;
@Property(nameInDb = "value")
private String value;
@ToMany(referencedJoinProperty = "diaryId")
private List<Semester> semesterList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 21166549)
private transient DiaryDao myDao;
@Generated(hash = 277096196)
public Diary(Long id, Long studentId, boolean current, String name, String value) {
this.id = id;
this.studentId = studentId;
this.current = current;
this.name = name;
this.value = value;
}
@Generated(hash = 112123061)
public Diary() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getStudentId() {
return this.studentId;
}
public Diary setStudentId(Long studentId) {
this.studentId = studentId;
return this;
}
public String getName() {
return this.name;
}
public Diary setName(String name) {
this.name = name;
return this;
}
public String getValue() {
return this.value;
}
public Diary setValue(String value) {
this.value = value;
return this;
}
public boolean getCurrent() {
return this.current;
}
public Diary 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 = 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;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 995060657)
public synchronized void resetSemesterList() {
semesterList = 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 = 629297785)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getDiaryDao() : null;
}
}

View File

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

View File

@ -1,353 +0,0 @@
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 = "Lessons",
active = true,
indexes = {@Index(value = "dayId,date,startTime,endTime", unique = true)}
)
public class Lesson implements Serializable {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "DAY_ID")
private Long dayId;
@Property(nameInDb = "NUMBER_OF_LESSON")
private String number;
@Property(nameInDb = "SUBJECT_NAME")
private String subject = "";
@Property(nameInDb = "TEACHER")
private String teacher = "";
@Property(nameInDb = "ROOM")
private String room = "";
@Property(nameInDb = "DESCRIPTION")
private String description = "";
@Property(nameInDb = "GROUP_NAME")
private String groupName = "";
@Property(nameInDb = "START_TIME")
private String startTime = "";
@Property(nameInDb = "END_TIME")
private String endTime = "";
@Property(nameInDb = "DATE")
private String date = "";
@Property(nameInDb = "IS_EMPTY")
private boolean isEmpty = false;
@Property(nameInDb = "IS_DIVISION_INTO_GROUP")
private boolean isDivisionIntoGroups = false;
@Property(nameInDb = "IS_PLANNING")
private boolean isPlanning = false;
@Property(nameInDb = "IS_REALIZED")
private boolean isRealized = false;
@Property(nameInDb = "IS_MOVED_CANCELED")
private boolean isMovedOrCanceled = false;
@Property(nameInDb = "IS_NEW_MOVED_IN_CANCELED")
private boolean isNewMovedInOrChanged = false;
private static final long serialVersionUID = 42L;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 610143130)
private transient LessonDao myDao;
@Generated(hash = 140778287)
public Lesson(Long id, Long dayId, String number, String subject, String teacher, String room,
String description, String groupName, String startTime, String endTime, String date,
boolean isEmpty, boolean isDivisionIntoGroups, boolean isPlanning, boolean isRealized,
boolean isMovedOrCanceled, boolean isNewMovedInOrChanged) {
this.id = id;
this.dayId = dayId;
this.number = number;
this.subject = subject;
this.teacher = teacher;
this.room = room;
this.description = description;
this.groupName = groupName;
this.startTime = startTime;
this.endTime = endTime;
this.date = date;
this.isEmpty = isEmpty;
this.isDivisionIntoGroups = isDivisionIntoGroups;
this.isPlanning = isPlanning;
this.isRealized = isRealized;
this.isMovedOrCanceled = isMovedOrCanceled;
this.isNewMovedInOrChanged = isNewMovedInOrChanged;
}
@Generated(hash = 1669664117)
public Lesson() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDayId() {
return this.dayId;
}
public void setDayId(Long dayId) {
this.dayId = dayId;
}
public String getNumber() {
return number;
}
public Lesson setNumber(String number) {
this.number = number;
return this;
}
public String getSubject() {
return subject;
}
public Lesson setSubject(String subject) {
this.subject = subject;
return this;
}
public String getTeacher() {
return teacher;
}
public Lesson setTeacher(String teacher) {
this.teacher = teacher;
return this;
}
public String getRoom() {
return room;
}
public Lesson setRoom(String room) {
this.room = room;
return this;
}
public String getDescription() {
return description;
}
public Lesson setDescription(String description) {
this.description = description;
return this;
}
public String getGroupName() {
return groupName;
}
public Lesson setGroupName(String groupName) {
this.groupName = groupName;
return this;
}
public String getStartTime() {
return startTime;
}
public Lesson setStartTime(String startTime) {
this.startTime = startTime;
return this;
}
public String getEndTime() {
return endTime;
}
public Lesson setEndTime(String endTime) {
this.endTime = endTime;
return this;
}
public String getDate() {
return date;
}
public Lesson setDate(String date) {
this.date = date;
return this;
}
public boolean isEmpty() {
return isEmpty;
}
public Lesson setEmpty(boolean empty) {
isEmpty = empty;
return this;
}
public boolean isDivisionIntoGroups() {
return isDivisionIntoGroups;
}
public Lesson setDivisionIntoGroups(boolean divisionIntoGroups) {
isDivisionIntoGroups = divisionIntoGroups;
return this;
}
public boolean isPlanning() {
return isPlanning;
}
public Lesson setPlanning(boolean planning) {
isPlanning = planning;
return this;
}
public boolean isRealized() {
return isRealized;
}
public Lesson setRealized(boolean realized) {
isRealized = realized;
return this;
}
public boolean isMovedOrCanceled() {
return isMovedOrCanceled;
}
public Lesson setMovedOrCanceled(boolean movedOrCanceled) {
isMovedOrCanceled = movedOrCanceled;
return this;
}
public boolean isNewMovedInOrChanged() {
return isNewMovedInOrChanged;
}
public Lesson setNewMovedInOrChanged(boolean newMovedInOrChanged) {
isNewMovedInOrChanged = newMovedInOrChanged;
return this;
}
public boolean getIsEmpty() {
return this.isEmpty;
}
public void setIsEmpty(boolean isEmpty) {
this.isEmpty = isEmpty;
}
public boolean getIsDivisionIntoGroups() {
return this.isDivisionIntoGroups;
}
public void setIsDivisionIntoGroups(boolean isDivisionIntoGroups) {
this.isDivisionIntoGroups = isDivisionIntoGroups;
}
public boolean getIsPlanning() {
return this.isPlanning;
}
public void setIsPlanning(boolean isPlanning) {
this.isPlanning = isPlanning;
}
public boolean getIsRealized() {
return this.isRealized;
}
public void setIsRealized(boolean isRealized) {
this.isRealized = isRealized;
}
public boolean getIsMovedOrCanceled() {
return this.isMovedOrCanceled;
}
public void setIsMovedOrCanceled(boolean isMovedOrCanceled) {
this.isMovedOrCanceled = isMovedOrCanceled;
}
public boolean getIsNewMovedInOrChanged() {
return this.isNewMovedInOrChanged;
}
public void setIsNewMovedInOrChanged(boolean isNewMovedInOrChanged) {
this.isNewMovedInOrChanged = isNewMovedInOrChanged;
}
/**
* 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 = 2078826279)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getLessonDao() : null;
}
}

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)
private Long id;
@Property(nameInDb = "USER_ID")
private Long userId;
@Property(nameInDb = "semester_id")
private Long semesterId;
@Property(nameInDb = "NAME")
@Property(nameInDb = "name")
private String name;
@Property(nameInDb = "PREDICTED_RATING")
@Property(nameInDb = "predicted_rating")
private String predictedRating;
@Property(nameInDb = "FINAL_RATING")
@Property(nameInDb = "final_rating")
private String finalRating;
@Property(nameInDb = "SEMESTER")
private String semester;
@ToMany(referencedJoinProperty = "subjectId")
private List<Grade> gradeList;
@ -48,15 +45,14 @@ public class Subject {
@Generated(hash = 1644932788)
private transient SubjectDao myDao;
@Generated(hash = 396325764)
public Subject(Long id, Long userId, String name, String predictedRating,
String finalRating, String semester) {
@Generated(hash = 1817932538)
public Subject(Long id, Long semesterId, String name, String predictedRating,
String finalRating) {
this.id = id;
this.userId = userId;
this.semesterId = semesterId;
this.name = name;
this.predictedRating = predictedRating;
this.finalRating = finalRating;
this.semester = semester;
}
@Generated(hash = 1617906264)
@ -64,25 +60,24 @@ public class Subject {
}
public Long getId() {
return id;
return this.id;
}
public Subject setId(Long id) {
public void setId(Long id) {
this.id = id;
return this;
}
public Long getUserId() {
return userId;
public Long getSemesterId() {
return this.semesterId;
}
public Subject setUserId(Long userId) {
this.userId = userId;
public Subject setSemesterId(Long semesterId) {
this.semesterId = semesterId;
return this;
}
public String getName() {
return name;
return this.name;
}
public Subject setName(String name) {
@ -91,7 +86,7 @@ public class Subject {
}
public String getPredictedRating() {
return predictedRating;
return this.predictedRating;
}
public Subject setPredictedRating(String predictedRating) {
@ -100,7 +95,7 @@ public class Subject {
}
public String getFinalRating() {
return finalRating;
return this.finalRating;
}
public Subject setFinalRating(String finalRating) {
@ -108,45 +103,6 @@ public class Subject {
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)}.
* Entity must attached to an entity context.
@ -183,6 +139,34 @@ public class Subject {
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. */
@Generated(hash = 937984622)
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

@ -0,0 +1,307 @@
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 = "TimetableLessons",
active = true,
indexes = {@Index(value = "dayId,date,startTime,endTime", unique = true)}
)
public class TimetableLesson implements Serializable {
private static final long serialVersionUID = 42L;
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "day_id")
private Long dayId;
@Property(nameInDb = "number")
private String number;
@Property(nameInDb = "subject")
private String subject = "";
@Property(nameInDb = "teacher")
private String teacher = "";
@Property(nameInDb = "room")
private String room = "";
@Property(nameInDb = "description")
private String description = "";
@Property(nameInDb = "group")
private String group = "";
@Property(nameInDb = "start_time")
private String startTime = "";
@Property(nameInDb = "end_time")
private String endTime = "";
@Property(nameInDb = "date")
private String date = "";
@Property(nameInDb = "empty")
private boolean empty = false;
@Property(nameInDb = "division_into_groups")
private boolean divisionIntoGroups = false;
@Property(nameInDb = "planning")
private boolean planning = false;
@Property(nameInDb = "realized")
private boolean realized = false;
@Property(nameInDb = "moved_canceled")
private boolean movedOrCanceled = false;
@Property(nameInDb = "new_moved_in_canceled")
private boolean newMovedInOrChanged = false;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 1119360138)
private transient TimetableLessonDao myDao;
@Generated(hash = 1955911128)
public TimetableLesson(Long id, Long dayId, String number, String subject,
String teacher, String room, String description, String group,
String startTime, String endTime, String date, boolean empty,
boolean divisionIntoGroups, boolean planning, boolean realized,
boolean movedOrCanceled, boolean newMovedInOrChanged) {
this.id = id;
this.dayId = dayId;
this.number = number;
this.subject = subject;
this.teacher = teacher;
this.room = room;
this.description = description;
this.group = group;
this.startTime = startTime;
this.endTime = endTime;
this.date = date;
this.empty = empty;
this.divisionIntoGroups = divisionIntoGroups;
this.planning = planning;
this.realized = realized;
this.movedOrCanceled = movedOrCanceled;
this.newMovedInOrChanged = newMovedInOrChanged;
}
@Generated(hash = 1878030142)
public TimetableLesson() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDayId() {
return this.dayId;
}
public TimetableLesson setDayId(Long dayId) {
this.dayId = dayId;
return this;
}
public String getNumber() {
return this.number;
}
public TimetableLesson setNumber(String number) {
this.number = number;
return this;
}
public String getSubject() {
return this.subject;
}
public TimetableLesson setSubject(String subject) {
this.subject = subject;
return this;
}
public String getTeacher() {
return this.teacher;
}
public TimetableLesson setTeacher(String teacher) {
this.teacher = teacher;
return this;
}
public String getRoom() {
return this.room;
}
public TimetableLesson setRoom(String room) {
this.room = room;
return this;
}
public String getDescription() {
return this.description;
}
public TimetableLesson setDescription(String description) {
this.description = description;
return this;
}
public String getGroup() {
return this.group;
}
public TimetableLesson setGroup(String group) {
this.group = group;
return this;
}
public String getStartTime() {
return this.startTime;
}
public TimetableLesson setStartTime(String startTime) {
this.startTime = startTime;
return this;
}
public String getEndTime() {
return this.endTime;
}
public TimetableLesson setEndTime(String endTime) {
this.endTime = endTime;
return this;
}
public String getDate() {
return this.date;
}
public TimetableLesson setDate(String date) {
this.date = date;
return this;
}
public boolean getEmpty() {
return this.empty;
}
public TimetableLesson setEmpty(boolean empty) {
this.empty = empty;
return this;
}
public boolean getDivisionIntoGroups() {
return this.divisionIntoGroups;
}
public TimetableLesson setDivisionIntoGroups(boolean divisionIntoGroups) {
this.divisionIntoGroups = divisionIntoGroups;
return this;
}
public boolean getPlanning() {
return this.planning;
}
public TimetableLesson setPlanning(boolean planning) {
this.planning = planning;
return this;
}
public boolean getRealized() {
return this.realized;
}
public TimetableLesson setRealized(boolean realized) {
this.realized = realized;
return this;
}
public boolean getMovedOrCanceled() {
return this.movedOrCanceled;
}
public TimetableLesson setMovedOrCanceled(boolean movedOrCanceled) {
this.movedOrCanceled = movedOrCanceled;
return this;
}
public boolean getNewMovedInOrChanged() {
return this.newMovedInOrChanged;
}
public TimetableLesson setNewMovedInOrChanged(boolean newMovedInOrChanged) {
this.newMovedInOrChanged = newMovedInOrChanged;
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 = 1885258429)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getTimetableLessonDao() : null;
}
}

View File

@ -13,35 +13,52 @@ import java.util.List;
@Entity(
nameInDb = "Weeks",
active = true,
indexes ={@Index(value = "userId,startDayDate", unique = true)}
indexes = {@Index(value = "diaryId,startDayDate", unique = true)}
)
public class Week {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "USER_ID")
private Long userId;
@Property(nameInDb = "diary_id")
private Long diaryId;
@Property(nameInDb = "START_DATE")
@Property(nameInDb = "start_day_date")
private String startDayDate = "";
@Property(nameInDb = "attendance_synced")
private boolean attendanceSynced = false;
@Property(nameInDb = "timetable_synced")
private boolean timetableSynced = false;
@Property(nameInDb = "exams_synced")
private boolean examsSynced = false;
@ToMany(referencedJoinProperty = "weekId")
private List<Day> dayList;
/** Used to resolve relations */
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/** Used for active entity operations. */
/**
* Used for active entity operations.
*/
@Generated(hash = 1019310398)
private transient WeekDao myDao;
@Generated(hash = 36829814)
public Week(Long id, Long userId, String startDayDate) {
@Generated(hash = 23357599)
public Week(Long id, Long diaryId, String startDayDate, boolean attendanceSynced,
boolean timetableSynced, boolean examsSynced) {
this.id = id;
this.userId = userId;
this.diaryId = diaryId;
this.startDayDate = startDayDate;
this.attendanceSynced = attendanceSynced;
this.timetableSynced = timetableSynced;
this.examsSynced = examsSynced;
}
@Generated(hash = 2135529658)
@ -57,12 +74,12 @@ public class Week {
return this;
}
public Long getUserId() {
return userId;
public Long getDiaryId() {
return diaryId;
}
public Week setUserId(Long userId) {
this.userId = userId;
public Week setDiaryId(Long diaryId) {
this.diaryId = diaryId;
return this;
}
@ -75,6 +92,33 @@ public class Week {
return this;
}
public boolean getAttendanceSynced() {
return this.attendanceSynced;
}
public Week setAttendanceSynced(boolean attendanceSynced) {
this.attendanceSynced = attendanceSynced;
return this;
}
public boolean getTimetableSynced() {
return this.timetableSynced;
}
public Week setTimetableSynced(boolean timetableSynced) {
this.timetableSynced = timetableSynced;
return this;
}
public Week setExamsSynced(boolean examsSynced) {
this.examsSynced = examsSynced;
return this;
}
public boolean getExamsSynced() {
return examsSynced;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
@ -97,7 +141,9 @@ public class Week {
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)
public synchronized void resetDayList() {
dayList = null;

View File

@ -0,0 +1,114 @@
package io.github.wulkanowy.data.db.dao.migrations;
import android.database.Cursor;
import android.os.AsyncTask;
import org.greenrobot.greendao.database.Database;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.github.wulkanowy.api.Diary;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.security.Scrambler;
public class Migration23 implements DbHelper.Migration {
@Override
public Integer getVersion() {
return 23;
}
@Override
public void runMigration(final Database db, final SharedPrefContract sharedPref, final Vulcan vulcan) throws Exception {
createDiaryTable(db);
migrateAccountsTable(db);
final Map<String, String> user = getAccountData(db);
vulcan.setCredentials(
user.get("email"),
Scrambler.decrypt(user.get("email"), user.get("password")),
user.get("symbol"),
user.get("school_id"),
"", // inserted in code bellow
""
);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
insertDiaries(db, vulcan.getStudentAndParent().getDiaries());
updateAccount(db, vulcan.getStudentAndParent().getStudentID());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void createDiaryTable(Database db) {
db.execSQL("DROP TABLE IF EXISTS Diaries");
db.execSQL("CREATE TABLE IF NOT EXISTS \"Diaries\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"STUDENT_ID\" TEXT," + // 1: studentId
"\"NAME\" TEXT," + // 2: name
"\"VALUE\" TEXT," + // 3: value
"\"IS_CURRENT\" INTEGER NOT NULL );"); // 4: isCurrent
}
private void migrateAccountsTable(Database db) {
db.execSQL("DROP TABLE IF EXISTS tmp_account");
db.execSQL("ALTER TABLE Accounts RENAME TO tmp_account");
db.execSQL("CREATE TABLE IF NOT EXISTS \"Accounts\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"REAL_ID\" TEXT," + // 1: realId
"\"SYMBOL\" TEXT," + // 2: symbol
"\"SCHOOL_ID\" TEXT," + // 3: schoolId
"\"NAME\" TEXT," + // 4: name
"\"E_MAIL\" TEXT," + // 5: email
"\"PASSWORD\" TEXT);"); // 6: password
// Add Indexes
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS IDX_Accounts_REAL_ID ON \"Accounts\" (\"REAL_ID\" ASC);");
db.execSQL("INSERT INTO Accounts(NAME, E_MAIL, PASSWORD, SYMBOL, SCHOOL_ID)" +
"SELECT `NAME`, `E-MAIL`, `PASSWORD`, `SYMBOL`, `SNPID` FROM tmp_account");
db.execSQL("DROP TABLE tmp_account");
}
private Map<String, String> getAccountData(Database db) {
Map<String, String> values = new HashMap<>();
Cursor cursor = db.rawQuery("SELECT SYMBOL, SCHOOL_ID, NAME, E_MAIL, PASSWORD FROM Accounts", null);
if (cursor.moveToFirst()) {
do {
values.put("symbol", cursor.getString(cursor.getColumnIndex("SYMBOL")));
values.put("school_id", cursor.getString(cursor.getColumnIndex("SCHOOL_ID")));
values.put("name", cursor.getString(cursor.getColumnIndex("NAME")));
values.put("email", cursor.getString(cursor.getColumnIndex("E_MAIL")));
values.put("password", cursor.getString(cursor.getColumnIndex("PASSWORD")));
} while (cursor.moveToNext());
}
cursor.close();
return values;
}
private void insertDiaries(Database db, List<Diary> list) {
for (Diary diary : list) {
db.execSQL("INSERT INTO Diaries(STUDENT_ID, NAME, VALUE, IS_CURRENT) VALUES(" +
"\"" + diary.getId() + "\"," +
"\"" + diary.getName() + "\"," +
"\"" + diary.getId() + "\"," +
"\"" + (diary.isCurrent() ? "1" : "0") + "\"" +
")");
}
}
private void updateAccount(Database db, String realId) {
db.execSQL("UPDATE Accounts SET REAL_ID = ?", new String[]{realId});
}
}

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

@ -1,5 +1,10 @@
package io.github.wulkanowy.data.db.resources;
import javax.inject.Singleton;
import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
@Singleton
public interface ResourcesContract {
String[] getSymbolsKeysArray();
@ -7,4 +12,6 @@ public interface ResourcesContract {
String[] getSymbolsValuesArray();
String getErrorLoginMessage(Exception e);
String getAttendanceLessonDescription(AttendanceLesson lesson);
}

View File

@ -3,6 +3,8 @@ package io.github.wulkanowy.data.db.resources;
import android.content.Context;
import android.content.res.Resources;
import com.crashlytics.android.Crashlytics;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
@ -11,20 +13,20 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.R;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.api.login.VulcanOfflineException;
import io.github.wulkanowy.api.NotLoggedInErrorException;
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.LogUtils;
import io.github.wulkanowy.utils.security.CryptoException;
@Singleton
public class AppResources implements ResourcesContract {
public class ResourcesRepository implements ResourcesContract {
private Resources resources;
@Inject
AppResources(@ApplicationContext Context context) {
ResourcesRepository(@ApplicationContext Context context) {
resources = context.getResources();
}
@ -41,6 +43,7 @@ public class AppResources implements ResourcesContract {
@Override
public String getErrorLoginMessage(Exception exception) {
LogUtils.error(AppConstant.APP_NAME + " encountered a error", exception);
Crashlytics.logException(exception);
if (exception instanceof CryptoException) {
return resources.getString(R.string.encrypt_failed_text);
@ -49,11 +52,40 @@ public class AppResources implements ResourcesContract {
} else if (exception instanceof SocketTimeoutException) {
return resources.getString(R.string.generic_timeout_error);
} else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) {
return resources.getString(R.string.login_denied_text);
} else if (exception instanceof VulcanOfflineException) {
return resources.getString(R.string.error_host_offline);
return resources.getString(R.string.login_failed_text);
} else {
return exception.getMessage();
}
}
@Override
public String getAttendanceLessonDescription(AttendanceLesson lesson) {
int id = R.string.attendance_present;
if (lesson.getAbsenceForSchoolReasons()) {
id = R.string.attendance_absence_for_school_reasons;
}
if (lesson.getAbsenceExcused()) {
id = R.string.attendance_absence_excused;
}
if (lesson.getAbsenceUnexcused()) {
id = R.string.attendance_absence_unexcused;
}
if (lesson.getExemption()) {
id = R.string.attendance_exemption;
}
if (lesson.getExcusedLateness()) {
id = R.string.attendance_excused_lateness;
}
if (lesson.getUnexcusedLateness()) {
id = R.string.attendance_unexcused_lateness;
}
return resources.getString(id);
}
}

View File

@ -1,33 +0,0 @@
package io.github.wulkanowy.data.db.shared;
import android.content.Context;
import android.content.SharedPreferences;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.di.annotations.SharedPreferencesInfo;
@Singleton
public class SharedPref implements SharedPrefContract {
private static final String SHARED_KEY_USER_ID = "USER_ID";
private final SharedPreferences sharedPreferences;
@Inject
SharedPref(@ApplicationContext Context context, @SharedPreferencesInfo String sharedName) {
sharedPreferences = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE);
}
@Override
public long getCurrentUserId() {
return sharedPreferences.getLong(SHARED_KEY_USER_ID, 0);
}
@Override
public void setCurrentUserId(long userId) {
sharedPreferences.edit().putLong(SHARED_KEY_USER_ID, userId).apply();
}
}

View File

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

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