Compare commits
99 Commits
Author | SHA1 | Date | |
---|---|---|---|
4b93a76693 | |||
d44a1dbce1 | |||
083765b020 | |||
b8a31c3faf | |||
378aba9716 | |||
5a4b8b22f3 | |||
8725640168 | |||
dab1bd4ac6 | |||
11578aa735 | |||
b63e28f9a9 | |||
072c504d2b | |||
7b7be1eef1 | |||
81d177c270 | |||
8d014ab7e9 | |||
a06d114127 | |||
0e16519baf | |||
dde5775a41 | |||
e2003e2538 | |||
228f680e5d | |||
306092ce45 | |||
d4b172e022 | |||
b4c765b482 | |||
3f1fff6d96 | |||
b59008a90f | |||
74c0dda999 | |||
2288ceffb8 | |||
ffe8511e3f | |||
34205e4a8b | |||
ef648c7f8b | |||
3592946e6f | |||
859f8dc319 | |||
9c97962e89 | |||
a4445a8a97 | |||
3f54d13b6b | |||
5685e73e46 | |||
e9b357e92d | |||
62bc00cd68 | |||
54e6aee82e | |||
3000c077c4 | |||
7d5072b529 | |||
052d5e3911 | |||
0014b74c6b | |||
08dd316aee | |||
95caa21f2a | |||
cd6e14b13b | |||
2cf262130e | |||
23183c9d7a | |||
be8ee4c835 | |||
3105e9e53b | |||
8e855bd375 | |||
67f83a4d2f | |||
d7f0fcad30 | |||
f29689c6cd | |||
dd2c69601a | |||
bfaa3d196b | |||
ffd20c94dd | |||
1740047aea | |||
cb2d4a905d | |||
89350e5793 | |||
4ef3334bf7 | |||
cb6d39fe15 | |||
09a8cc38f9 | |||
3443b01b9a | |||
7dde13585c | |||
176d17e1ec | |||
119e38254a | |||
6fcf09e2b7 | |||
6927ac0e4f | |||
2fd5b0f6ee | |||
b7a6b71a4d | |||
ce00c7025a | |||
5c558ae1f9 | |||
0708d84b98 | |||
b22d95392b | |||
78d57ca746 | |||
0aa8c5605d | |||
cb6afb137f | |||
c72e7748e2 | |||
5c9f10fa50 | |||
cdd3d6a53b | |||
8431661d54 | |||
3dabb11473 | |||
63b4ed42ca | |||
2bb2341d0f | |||
797e233809 | |||
64b964ca18 | |||
c9bdac6a66 | |||
83b4f359bc | |||
a094d4f0d9 | |||
3aca34340d | |||
a0313827ce | |||
3799fa910b | |||
828e76821b | |||
e050982de2 | |||
69fc4bf874 | |||
c3803b1c96 | |||
e274949257 | |||
bc4b150858 | |||
e187493e01 |
@ -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/
|
||||
@ -78,11 +87,8 @@ jobs:
|
||||
name: Upload unit code coverage to codecov
|
||||
command: bash <(curl -s https://codecov.io/bash) -F app
|
||||
- store_artifacts:
|
||||
path: ./app/build/reports/tests/
|
||||
destination: tests_reports/
|
||||
- store_artifacts:
|
||||
path: ./app/build/reports/jacoco/jacocoTestDebugUnitTestReport/
|
||||
destination: coverage_reports/
|
||||
path: ./app/build/reports/
|
||||
destination: reports/
|
||||
- store_test_results:
|
||||
path: ./app/build/test-results
|
||||
- persist_to_workspace:
|
||||
@ -103,11 +109,8 @@ jobs:
|
||||
name: Upload code coverage to codecov
|
||||
command: bash <(curl -s https://codecov.io/bash) -F api
|
||||
- store_artifacts:
|
||||
path: ./api/build/reports/tests/
|
||||
destination: tests_reports/
|
||||
- store_artifacts:
|
||||
path: ./api/build/reports/jacoco/test/
|
||||
destination: coverage_reports/
|
||||
path: ./api/build/reports/
|
||||
destination: reports/
|
||||
- store_test_results:
|
||||
path: ./api/build/test-results
|
||||
- persist_to_workspace:
|
||||
@ -121,11 +124,14 @@ jobs:
|
||||
- *attach_workspace
|
||||
- run:
|
||||
name: Setup emulator
|
||||
command: sdkmanager "system-images;android-19;google_apis;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-19;google_apis;armeabi-v7a"
|
||||
command: sdkmanager "system-images;android-16;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-16;default;armeabi-v7a"
|
||||
- run:
|
||||
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,30 +175,69 @@ 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
|
||||
|
||||
build_check_tests:
|
||||
build-test-deploy:
|
||||
jobs:
|
||||
- build
|
||||
- build:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- lint:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build
|
||||
- app-test:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build
|
||||
- api-test:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build
|
||||
- instrumented:
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build
|
||||
- sonarcube:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build
|
||||
- lint
|
||||
- app-test
|
||||
- api-test
|
||||
- instrumented
|
||||
- deploy:
|
||||
requires:
|
||||
- instrumented
|
||||
filters:
|
||||
tags:
|
||||
only: /\d+\.\d+\.\d+/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
|
||||
|
@ -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
|
||||
|
13
README.md
13
README.md
@ -1,12 +1,15 @@
|
||||
# Wulkanowy
|
||||
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://www.versioneye.com/user/projects/5969ff0b0fb24f004f8c711b)
|
||||
[](https://circleci.com/gh/wulkanowy/wulkanowy)
|
||||
[](https://circleci.com/gh/wulkanowy/wulkanowy)
|
||||
[](https://www.bitrise.io/app/daeff1893f3c8128)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://bettercodehub.com/)
|
||||
[](https://scrutinizer-ci.com/g/wulkanowy/wulkanowy/?branch=master)
|
||||
[](https://bintray.com/wulkanowy/wulkanowy/api)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
|
||||
[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&utm_source=vcs)
|
||||
|
||||
Wulkanowy to projekt aplikacji na androida ułatwiającej używanie dziennika VULCANa.
|
||||
[Pobierz wersję DEV](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/0)
|
||||
|
||||
Androidowy klient dziennika VULCAN UONET+.
|
||||
|
@ -1,4 +1,5 @@
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'org.sonarqube'
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
@ -28,12 +29,15 @@ 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"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jApi"
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.mockito:mockito-core:2.13.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
testImplementation "junit:junit:$junit"
|
||||
testImplementation "org.mockito:mockito-core:$mockito"
|
||||
}
|
||||
|
||||
version = PUBLISH_VERSION
|
||||
|
@ -3,58 +3,175 @@ package io.github.wulkanowy.api;
|
||||
import org.jsoup.Connection;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.github.wulkanowy.api.generic.School;
|
||||
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 String schoolId;
|
||||
|
||||
private List<School> schools;
|
||||
|
||||
private Date lastSuccessRequest;
|
||||
|
||||
private Cookies cookies = new Cookies();
|
||||
|
||||
Client(String protocol, String host, String symbol) {
|
||||
this.protocol = protocol;
|
||||
this.host = host;
|
||||
private static final Logger logger = LoggerFactory.getLogger(Client.class);
|
||||
|
||||
Client(String email, String password, String symbol, String schoolId) {
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.symbol = symbol;
|
||||
this.schoolId = schoolId;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
logger.info("Not logged. Login...");
|
||||
|
||||
clearCookies();
|
||||
new Login(this).login(email, password, symbol);
|
||||
lastSuccessRequest = new Date();
|
||||
|
||||
logger.info("Login successful on {} at {}", getHost(), new Date());
|
||||
}
|
||||
|
||||
private boolean isLoggedIn() {
|
||||
logger.trace("Last success request: {}", lastSuccessRequest);
|
||||
logger.trace("Cookies: {}", getCookies().size());
|
||||
|
||||
return getCookies().size() > 0 && lastSuccessRequest != null &&
|
||||
5 > 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() {
|
||||
private Map<String, String> getCookies() {
|
||||
return cookies.getItems();
|
||||
}
|
||||
|
||||
private String getFilledUrl(String url) {
|
||||
public void clearCookies() {
|
||||
cookies = new Cookies();
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setSchools(List<School> schools) {
|
||||
this.schools = schools;
|
||||
this.schoolId = schools.get(0).getId();
|
||||
}
|
||||
|
||||
public List<School> getSchools() throws IOException, VulcanException {
|
||||
login();
|
||||
return schools;
|
||||
}
|
||||
|
||||
public String getSchoolId() throws IOException, VulcanException {
|
||||
return schoolId != null ? schoolId : getSchools().get(0).getId();
|
||||
}
|
||||
|
||||
String getFilledUrl(String url) {
|
||||
return url
|
||||
.replace("{schema}", protocol)
|
||||
.replace("{host}", host.replace(":", "%253A"))
|
||||
.replace("{symbol}", symbol == null ? "Default" : symbol);
|
||||
.replace("{host}", host)
|
||||
.replace("{symbol}", symbol)
|
||||
.replace("{ID}", schoolId != null ? schoolId : "");
|
||||
}
|
||||
|
||||
Document getPageByUrl(String url) throws IOException {
|
||||
Connection.Response response = Jsoup.connect(getFilledUrl(url))
|
||||
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);
|
||||
}
|
||||
|
||||
url = getFilledUrl(url);
|
||||
|
||||
logger.debug("GET {}", url);
|
||||
|
||||
Connection.Response response = Jsoup.connect(url)
|
||||
.followRedirects(true)
|
||||
.cookies(getCookies())
|
||||
.execute();
|
||||
|
||||
this.cookies.addItems(response.cookies());
|
||||
|
||||
return response.parse();
|
||||
Document doc = checkForErrors(response.parse(), response.statusCode());
|
||||
|
||||
if (loginBefore) {
|
||||
lastSuccessRequest = new Date();
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public Document postPageByUrl(String url, String[][] params) throws IOException {
|
||||
Connection connection = Jsoup.connect(getFilledUrl(url));
|
||||
public synchronized Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException {
|
||||
url = getFilledUrl(url);
|
||||
|
||||
logger.debug("POST {}", url);
|
||||
|
||||
Connection connection = Jsoup.connect(url);
|
||||
|
||||
for (String[] data : params) {
|
||||
connection.data(data[0], data[1]);
|
||||
@ -68,11 +185,19 @@ public class Client {
|
||||
|
||||
this.cookies.addItems(response.cookies());
|
||||
|
||||
return response.parse();
|
||||
response.bufferUp(); // fixes cert parsing issues #109
|
||||
|
||||
return checkForErrors(response.parse(), response.statusCode());
|
||||
}
|
||||
|
||||
public String getJsonStringByUrl(String url) throws IOException {
|
||||
Connection.Response response = Jsoup.connect(getFilledUrl(url))
|
||||
public String getJsonStringByUrl(String url) throws IOException, VulcanException {
|
||||
login();
|
||||
|
||||
url = getFilledUrl(url);
|
||||
|
||||
logger.debug("GET {}", url);
|
||||
|
||||
Connection.Response response = Jsoup.connect(url)
|
||||
.followRedirects(true)
|
||||
.ignoreContentType(true)
|
||||
.cookies(getCookies())
|
||||
@ -83,8 +208,14 @@ public class Client {
|
||||
return response.body();
|
||||
}
|
||||
|
||||
public String postJsonStringByUrl(String url, String[][] params) throws IOException {
|
||||
Connection connection = Jsoup.connect(getFilledUrl(url));
|
||||
public String postJsonStringByUrl(String url, String[][] params) throws IOException, VulcanException {
|
||||
login();
|
||||
|
||||
url = getFilledUrl(url);
|
||||
|
||||
logger.debug("POST {}", url);
|
||||
|
||||
Connection connection = Jsoup.connect(url);
|
||||
|
||||
for (String[] data : params) {
|
||||
connection.data(data[0], data[1]);
|
||||
@ -101,4 +232,24 @@ public class Client {
|
||||
|
||||
return response.body();
|
||||
}
|
||||
|
||||
Document checkForErrors(Document doc, int code) 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 NotLoggedInErrorException(title + " " + doc.body() + ", status: " + code);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
53
api/src/main/java/io/github/wulkanowy/api/DateTimeUtils.kt
Normal file
53
api/src/main/java/io/github/wulkanowy/api/DateTimeUtils.kt
Normal file
@ -0,0 +1,53 @@
|
||||
package io.github.wulkanowy.api
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
const val LOG_DATE_PATTERN = "dd.MM.yyyy"
|
||||
const val API_DATE_PATTERN = "yyyy-MM-dd"
|
||||
|
||||
const val TICKS_AT_EPOCH = 621355968000000000L
|
||||
const val TICKS_PER_MILLISECOND = 10000
|
||||
|
||||
fun getFormattedDate(date: String): String {
|
||||
return getFormattedDate(date, API_DATE_PATTERN)
|
||||
}
|
||||
|
||||
fun getFormattedDate(date: String, format: String): String {
|
||||
return getFormattedDate(date, LOG_DATE_PATTERN, format)
|
||||
}
|
||||
|
||||
fun getFormattedDate(date: String, fromFormat: String, toFormat: String): String {
|
||||
val sdf = SimpleDateFormat(fromFormat, Locale.ROOT)
|
||||
val d = sdf.parse(date)
|
||||
sdf.applyPattern(toFormat)
|
||||
|
||||
return sdf.format(d)
|
||||
}
|
||||
|
||||
fun getDateAsTick(dateString: String?): String {
|
||||
if (dateString.isNullOrEmpty()) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return getDateAsTick(dateString as String, API_DATE_PATTERN).toString()
|
||||
}
|
||||
|
||||
fun getDateAsTick(dateString: String, dateFormat: String): Long {
|
||||
val format = SimpleDateFormat(dateFormat, Locale.ROOT)
|
||||
format.timeZone = TimeZone.getTimeZone("UTC")
|
||||
val dateObject = format.parse(dateString)
|
||||
|
||||
return getDateAsTick(dateObject)
|
||||
}
|
||||
|
||||
fun getDateAsTick(date: Date): Long {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.time = date
|
||||
|
||||
return calendar.timeInMillis * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH
|
||||
}
|
||||
|
||||
fun getDate(netTicks: Long): Date {
|
||||
return Date((netTicks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND)
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package io.github.wulkanowy.api;
|
||||
|
||||
public class NotLoggedInErrorException extends VulcanException {
|
||||
|
||||
public NotLoggedInErrorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package io.github.wulkanowy.api;
|
||||
|
||||
public class Semester {
|
||||
|
||||
private String number = "";
|
||||
|
||||
private String id = "";
|
||||
|
||||
private boolean isCurrent = false;
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public Semester setNumber(String number) {
|
||||
this.number = number;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Semester setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isCurrent() {
|
||||
return isCurrent;
|
||||
}
|
||||
|
||||
public Semester setCurrent(boolean current) {
|
||||
isCurrent = current;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -6,21 +6,30 @@ import org.jsoup.nodes.Element;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
|
||||
import io.github.wulkanowy.api.generic.Diary;
|
||||
import io.github.wulkanowy.api.generic.ParamItem;
|
||||
import io.github.wulkanowy.api.generic.Semester;
|
||||
import io.github.wulkanowy.api.generic.Student;
|
||||
|
||||
public interface SnP {
|
||||
|
||||
String getId();
|
||||
void setDiaryID(String id);
|
||||
|
||||
void storeContextCookies() throws IOException, NotLoggedInErrorException;
|
||||
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);
|
||||
}
|
||||
|
@ -3,85 +3,108 @@ package io.github.wulkanowy.api;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
|
||||
import io.github.wulkanowy.api.generic.Diary;
|
||||
import io.github.wulkanowy.api.generic.ParamItem;
|
||||
import io.github.wulkanowy.api.generic.Semester;
|
||||
import io.github.wulkanowy.api.generic.Student;
|
||||
|
||||
public class StudentAndParent implements SnP {
|
||||
|
||||
private static final String START_PAGE_URL = "{schema}://uonetplus.{host}/{symbol}/Start.mvc/Index";
|
||||
|
||||
private static final String BASE_URL = "{schema}://uonetplus-opiekun.{host}/{symbol}/{ID}/";
|
||||
|
||||
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie";
|
||||
|
||||
private Client client;
|
||||
|
||||
private String id;
|
||||
private String studentID;
|
||||
|
||||
StudentAndParent(Client client) {
|
||||
private String diaryID;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StudentAndParent.class);
|
||||
|
||||
StudentAndParent(Client client, String studentID, String diaryID) {
|
||||
this.client = client;
|
||||
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(BASE_URL);
|
||||
|
||||
private String getBaseUrl() {
|
||||
return BASE_URL.replace("{ID}", getId());
|
||||
}
|
||||
if (doc.select("#idSection").isEmpty()) {
|
||||
logger.error("Expected SnP page, got page with title: {} {}", doc.title(), doc.selectFirst("body"));
|
||||
throw new VulcanException("Nieznany błąd podczas pobierania danych. Strona: " + doc.title());
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
Student student = getCurrent(getStudents(doc));
|
||||
studentID = student.getId();
|
||||
|
||||
public void storeContextCookies() throws IOException, NotLoggedInErrorException {
|
||||
client.getPageByUrl(getSnpHomePageUrl());
|
||||
}
|
||||
|
||||
String getSnpHomePageUrl() throws IOException, NotLoggedInErrorException {
|
||||
if (null != getId()) {
|
||||
return getBaseUrl();
|
||||
Diary diary = getCurrent(getDiaries(doc));
|
||||
diaryID = diary.getId();
|
||||
}
|
||||
|
||||
// get url to uonetplus-opiekun.vulcan.net.pl
|
||||
Document startPage = client.getPageByUrl(START_PAGE_URL);
|
||||
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first();
|
||||
|
||||
if (null == studentTileLink) {
|
||||
throw new NotLoggedInErrorException();
|
||||
}
|
||||
|
||||
String snpPageUrl = studentTileLink.attr("href");
|
||||
|
||||
this.id = getExtractedIdFromUrl(snpPageUrl);
|
||||
|
||||
return snpPageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
String getExtractedIdFromUrl(String snpPageUrl) throws NotLoggedInErrorException {
|
||||
String[] path = snpPageUrl.split(client.getHost())[1].split("/");
|
||||
|
||||
if (5 != path.length) {
|
||||
throw new NotLoggedInErrorException();
|
||||
}
|
||||
|
||||
return path[2];
|
||||
public String getStudentID() {
|
||||
return studentID;
|
||||
}
|
||||
|
||||
public String getRowDataChildValue(Element e, int index) {
|
||||
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);
|
||||
|
||||
Document doc = client.getPageByUrl(BASE_URL + url, true, cookies);
|
||||
|
||||
if (!doc.title().startsWith("Witryna ucznia i rodzica")) {
|
||||
logger.error("Expected SnP page, got page with title: {} {}", doc.title(), doc.selectFirst("body"));
|
||||
throw new VulcanException("Nieznany błąd podczas pobierania danych. Strona: " + doc.title());
|
||||
}
|
||||
|
||||
if (doc.title().endsWith("Strona główna")) {
|
||||
throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public List<Diary> getDiaries() throws IOException, VulcanException {
|
||||
return getDiaries(client.getPageByUrl(BASE_URL));
|
||||
}
|
||||
|
||||
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(BASE_URL));
|
||||
}
|
||||
|
||||
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 +115,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 +128,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"));
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
package io.github.wulkanowy.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.api.attendance.AttendanceStatistics;
|
||||
import io.github.wulkanowy.api.attendance.AttendanceTable;
|
||||
import io.github.wulkanowy.api.exams.ExamsWeek;
|
||||
import io.github.wulkanowy.api.generic.School;
|
||||
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.mobile.RegisterDevice;
|
||||
import io.github.wulkanowy.api.mobile.RegisteredDevices;
|
||||
import io.github.wulkanowy.api.notes.AchievementsList;
|
||||
import io.github.wulkanowy.api.notes.NotesList;
|
||||
import io.github.wulkanowy.api.school.SchoolInfo;
|
||||
@ -24,173 +25,109 @@ 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 studentId;
|
||||
|
||||
public void setClient(Client client) {
|
||||
this.client = client;
|
||||
private String diaryId;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Vulcan.class);
|
||||
|
||||
public void setCredentials(String email, String password, String symbol, String schoolId, String studentId, String diaryId) {
|
||||
this.studentId = studentId;
|
||||
this.diaryId = diaryId;
|
||||
|
||||
client = new Client(email, password, symbol, schoolId);
|
||||
|
||||
logger.debug("Client created with symbol " + 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("Vulcan must be initialized by calling setCredentials() prior to fetch data");
|
||||
}
|
||||
}
|
||||
|
||||
protected Client getClient() {
|
||||
if (null != client) {
|
||||
return client;
|
||||
}
|
||||
|
||||
client = new Client(getProtocolSchema(), getLogHost(), symbol);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
protected Login getLogin() {
|
||||
if (null != login) {
|
||||
return login;
|
||||
}
|
||||
|
||||
login = new Login(getClient());
|
||||
|
||||
return login;
|
||||
public String getSymbol() throws NotLoggedInErrorException {
|
||||
return getClient().getSymbol();
|
||||
}
|
||||
|
||||
public SnP getStudentAndParent() throws IOException, NotLoggedInErrorException {
|
||||
if (0 == getClient().getCookies().size()) {
|
||||
throw new NotLoggedInErrorException();
|
||||
}
|
||||
|
||||
if (null != snp) {
|
||||
return snp;
|
||||
}
|
||||
|
||||
snp = createSnp(getClient(), id);
|
||||
|
||||
snp.storeContextCookies();
|
||||
|
||||
return snp;
|
||||
public List<School> getSchools() throws VulcanException, IOException {
|
||||
return getClient().getSchools();
|
||||
}
|
||||
|
||||
SnP createSnp(Client client, String id) {
|
||||
if (null == id) {
|
||||
return new StudentAndParent(client);
|
||||
public SnP getStudentAndParent() throws VulcanException, IOException {
|
||||
if (null != this.snp) {
|
||||
return this.snp;
|
||||
}
|
||||
|
||||
return new StudentAndParent(client, id);
|
||||
this.snp = new StudentAndParent(getClient(), studentId, diaryId)
|
||||
.setUp();
|
||||
|
||||
return this.snp;
|
||||
}
|
||||
|
||||
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 RegisteredDevices getRegisteredDevices() throws VulcanException, IOException {
|
||||
return new RegisteredDevices(getStudentAndParent());
|
||||
}
|
||||
|
||||
public RegisterDevice getRegisterDevice() throws VulcanException, IOException {
|
||||
return new RegisterDevice(getStudentAndParent());
|
||||
}
|
||||
|
||||
public Messages getMessages() throws VulcanException {
|
||||
return new Messages(getClient());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package io.github.wulkanowy.api;
|
||||
|
||||
public class VulcanOfflineException extends VulcanException {
|
||||
|
||||
VulcanOfflineException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -8,33 +8,42 @@ 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.Day;
|
||||
import io.github.wulkanowy.api.generic.Lesson;
|
||||
import io.github.wulkanowy.api.generic.Week;
|
||||
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
|
||||
|
||||
public class AttendanceTable {
|
||||
|
||||
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, VulcanException {
|
||||
return getWeekTable("");
|
||||
}
|
||||
|
||||
public Week<Day> getWeekTable(String tick) throws IOException {
|
||||
Element table = snp.getSnPPageDocument(attendancePageUrl + tick)
|
||||
public Week<Day> getWeekTable(String date) throws IOException, VulcanException {
|
||||
Element table = snp.getSnPPageDocument(ATTENDANCE_PAGE_URL + getDateAsTick(date))
|
||||
.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>");
|
||||
|
||||
days.add(new Day()
|
||||
.setDayName(dayHeaderCell[0])
|
||||
.setDate(getFormattedDate(dayHeaderCell[1].trim()))
|
||||
);
|
||||
}
|
||||
|
||||
Elements hoursInDays = table.select("tbody tr");
|
||||
@ -46,26 +55,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(Integer.valueOf(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 +107,5 @@ public class AttendanceTable {
|
||||
lesson.setEmpty(true);
|
||||
break;
|
||||
}
|
||||
|
||||
return lesson;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
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;
|
||||
@ -9,8 +10,12 @@ 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.Week;
|
||||
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
|
||||
|
||||
public class ExamsWeek {
|
||||
|
||||
private static final String EXAMS_PAGE_URL = "Sprawdziany.mvc/Terminarz?rodzajWidoku=2&data=";
|
||||
@ -21,12 +26,12 @@ public class ExamsWeek {
|
||||
this.snp = snp;
|
||||
}
|
||||
|
||||
public Week<ExamDay> getCurrent() throws IOException {
|
||||
public Week<ExamDay> getCurrent() throws IOException, VulcanException {
|
||||
return getWeek("", true);
|
||||
}
|
||||
|
||||
public Week<ExamDay> getWeek(String tick, final boolean onlyNotEmpty) throws IOException {
|
||||
Document examsPage = snp.getSnPPageDocument(EXAMS_PAGE_URL + tick);
|
||||
public Week<ExamDay> getWeek(String date, final boolean onlyNotEmpty) throws IOException, VulcanException {
|
||||
Document examsPage = snp.getSnPPageDocument(EXAMS_PAGE_URL + getDateAsTick(date));
|
||||
Elements examsDays = examsPage.select(".mainContainer > div:not(.navigation)");
|
||||
|
||||
List<ExamDay> days = new ArrayList<>();
|
||||
@ -40,7 +45,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 +57,17 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
@ -41,23 +37,8 @@ public class Day {
|
||||
return dayName;
|
||||
}
|
||||
|
||||
public void setDayName(String dayName) {
|
||||
public Day 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;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
38
api/src/main/java/io/github/wulkanowy/api/generic/Diary.java
Normal file
38
api/src/main/java/io/github/wulkanowy/api/generic/Diary.java
Normal file
@ -0,0 +1,38 @@
|
||||
package io.github.wulkanowy.api.generic;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package io.github.wulkanowy.api.generic;
|
||||
|
||||
public class Lesson {
|
||||
|
||||
private String number = "";
|
||||
private int number = 0;
|
||||
|
||||
private String subject = "";
|
||||
|
||||
@ -48,12 +48,13 @@ public class Lesson {
|
||||
|
||||
private boolean isExemption = false;
|
||||
|
||||
public String getNumber() {
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(String number) {
|
||||
public Lesson setNumber(int number) {
|
||||
this.number = number;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
|
@ -0,0 +1,12 @@
|
||||
package io.github.wulkanowy.api.generic;
|
||||
|
||||
public interface ParamItem {
|
||||
|
||||
ParamItem setId(String id);
|
||||
|
||||
ParamItem setName(String name);
|
||||
|
||||
ParamItem setCurrent(boolean isCurrent);
|
||||
|
||||
boolean isCurrent();
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package io.github.wulkanowy.api.generic
|
||||
|
||||
data class School(
|
||||
val name: String,
|
||||
val id: String,
|
||||
val current: Boolean
|
||||
)
|
@ -0,0 +1,37 @@
|
||||
package io.github.wulkanowy.api.generic;
|
||||
|
||||
public class Semester implements ParamItem {
|
||||
|
||||
private String id = "";
|
||||
|
||||
private String name = "";
|
||||
|
||||
private boolean current = false;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Semester setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Semester setName(String number) {
|
||||
this.name = number;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public Semester setCurrent(boolean current) {
|
||||
this.current = current;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package io.github.wulkanowy.api.generic;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -5,78 +5,71 @@ 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 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;
|
||||
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
|
||||
|
||||
public class GradesList {
|
||||
|
||||
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie?details=2&okres=";
|
||||
|
||||
private SnP snp = null;
|
||||
|
||||
private List<Grade> grades = new ArrayList<>();
|
||||
private SnP snp;
|
||||
|
||||
public GradesList(SnP snp) {
|
||||
this.snp = snp;
|
||||
}
|
||||
|
||||
private String getGradesPageUrl() {
|
||||
return GRADES_PAGE_URL;
|
||||
}
|
||||
|
||||
public List<Grade> getAll() throws IOException, ParseException {
|
||||
return getAll("");
|
||||
}
|
||||
|
||||
public List<Grade> getAll(String semester) throws IOException, ParseException {
|
||||
Document gradesPage = snp.getSnPPageDocument(getGradesPageUrl() + semester);
|
||||
public List<Grade> getAll(String semester) throws IOException, VulcanException {
|
||||
Document gradesPage = snp.getSnPPageDocument(GRADES_PAGE_URL + semester);
|
||||
Elements gradesRows = gradesPage.select(".ocenySzczegoly-table > tbody > tr");
|
||||
Semester currentSemester = snp.getCurrentSemester(snp.getSemesters(gradesPage));
|
||||
|
||||
List<Grade> grades = new ArrayList<>();
|
||||
|
||||
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) {
|
||||
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 = getFormattedDate(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;
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -2,81 +2,125 @@ 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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.api.Client;
|
||||
import io.github.wulkanowy.api.NotLoggedInErrorException;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
|
||||
public class Login {
|
||||
|
||||
private static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
|
||||
"?ReturnUrl=%2F{symbol}%2FFS%2FLS%3Fwa%3Dwsignin1.0%26wtrealm%3D" +
|
||||
protected static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn";
|
||||
|
||||
private static final String LOGIN_PAGE_URL_QUERY = "?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;
|
||||
private static final Logger logger = LoggerFactory.getLogger(Login.class);
|
||||
|
||||
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 void login(String email, String password, String symbol) throws VulcanException, IOException {
|
||||
Document certDoc = sendCredentials(email, password);
|
||||
|
||||
return sendCertificate(certificate, symbol);
|
||||
if ("Błąd".equals(certDoc.title())) {
|
||||
client.clearCookies();
|
||||
throw new NotLoggedInErrorException(certDoc.body().text());
|
||||
}
|
||||
|
||||
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();
|
||||
Document nextDoc = sendCredentialsData(credentials, LOGIN_PAGE_URL + LOGIN_PAGE_URL_QUERY.replace(":", "%253A"));
|
||||
|
||||
Element errorMessage = nextDoc.selectFirst(".ErrorMessage, #ErrorTextLabel");
|
||||
if (null != errorMessage) {
|
||||
throw new BadCredentialsException(errorMessage.text());
|
||||
}
|
||||
|
||||
return html.select("input[name=wresult]").attr("value");
|
||||
return nextDoc;
|
||||
}
|
||||
|
||||
String sendCertificate(String certificate, String defaultSymbol)
|
||||
throws IOException, LoginErrorException, AccountPermissionException, VulcanOfflineException {
|
||||
this.symbol = findSymbol(defaultSymbol, certificate);
|
||||
client.setSymbol(this.symbol);
|
||||
private Document sendCredentialsData(String[][] credentials, String nextUrl) throws IOException, VulcanException {
|
||||
Element formFirst = client.getPageByUrl(nextUrl, false).selectFirst("#form1");
|
||||
|
||||
Document html = client.postPageByUrl(LOGIN_ENDPOINT_PAGE_URL, new String[][]{
|
||||
if (null != formFirst) { // only on adfs login
|
||||
Document formSecond = client.postPageByUrl(
|
||||
formFirst.attr("abs:action"),
|
||||
getFormStateParams(formFirst, "", "")
|
||||
);
|
||||
credentials = getFormStateParams(formSecond, credentials[0][1], credentials[1][1]);
|
||||
nextUrl = formSecond.selectFirst("#form1").attr("abs:action");
|
||||
}
|
||||
|
||||
return client.postPageByUrl(nextUrl, credentials);
|
||||
}
|
||||
|
||||
private String[][] getFormStateParams(Element form, String email, String password) {
|
||||
return new String[][]{
|
||||
{"__VIEWSTATE", form.select("#__VIEWSTATE").val()},
|
||||
{"__VIEWSTATEGENERATOR", form.select("#__VIEWSTATEGENERATOR").val()},
|
||||
{"__EVENTVALIDATION", form.select("#__EVENTVALIDATION").val()},
|
||||
{"__db", form.select("input[name=__db]").val()},
|
||||
{"PassiveSignInButton.x", "0"},
|
||||
{"PassiveSignInButton.y", "0"},
|
||||
{"SubmitButton.x", "0"},
|
||||
{"SubmitButton.y", "0"},
|
||||
{"UsernameTextBox", email},
|
||||
{"PasswordTextBox", password},
|
||||
};
|
||||
}
|
||||
|
||||
void sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
|
||||
client.setSymbol(findSymbol(defaultSymbol, doc.select("input[name=wresult]").val()));
|
||||
|
||||
Document targetDoc = sendCertData(doc);
|
||||
String title = targetDoc.title();
|
||||
|
||||
if ("Working...".equals(title)) { // on adfs login
|
||||
logger.info("ADFS login");
|
||||
title = sendCertData(targetDoc).title();
|
||||
}
|
||||
|
||||
if ("Logowanie".equals(title)) {
|
||||
throw new AccountPermissionException("No account access. Try another symbol");
|
||||
}
|
||||
|
||||
if (!"Uonet+".equals(title)) {
|
||||
logger.debug("Login failed. Body: {}", targetDoc.body());
|
||||
throw new LoginErrorException("Expected page title `UONET+`, got " + title);
|
||||
}
|
||||
|
||||
client.setSchools(new StartPage(client).getSchools(targetDoc));
|
||||
}
|
||||
|
||||
private Document sendCertData(Document doc) throws IOException, VulcanException {
|
||||
String url = doc.select("form[name=hiddenform]").attr("action");
|
||||
|
||||
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 +128,19 @@ 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()) {
|
||||
if (instances.isEmpty()) { // on adfs login
|
||||
return "";
|
||||
}
|
||||
|
||||
return els.get(1).text();
|
||||
if (instances.size() < 2) { // 1st index is always `Default`
|
||||
throw new AccountPermissionException("First login detected, specify symbol");
|
||||
}
|
||||
|
||||
return instances.get(1).text();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
package io.github.wulkanowy.api.login;
|
||||
|
||||
public class NotLoggedInErrorException extends Exception {
|
||||
}
|
45
api/src/main/java/io/github/wulkanowy/api/login/StartPage.kt
Normal file
45
api/src/main/java/io/github/wulkanowy/api/login/StartPage.kt
Normal file
@ -0,0 +1,45 @@
|
||||
package io.github.wulkanowy.api.login
|
||||
|
||||
import io.github.wulkanowy.api.Client
|
||||
import io.github.wulkanowy.api.VulcanException
|
||||
import io.github.wulkanowy.api.generic.School
|
||||
import org.jsoup.nodes.Document
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class StartPage(val client: Client) {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(StartPage::class.java)
|
||||
|
||||
fun getSchools(startPage: Document): MutableList<School> {
|
||||
val schoolList = mutableListOf<School>()
|
||||
|
||||
val snpLinks = startPage.select(".panel.linkownia.pracownik.klient a")
|
||||
|
||||
logger.debug("SnP links: {}", snpLinks.size)
|
||||
|
||||
if (snpLinks.isEmpty()) {
|
||||
throw VulcanException("Na pewno używasz konta z dostępem do Witryny ucznia i rodzica?")
|
||||
}
|
||||
|
||||
snpLinks.map {
|
||||
schoolList.add(School(
|
||||
it.text(),
|
||||
getExtractedIdFromUrl(it.attr("href")),
|
||||
it == snpLinks.first()
|
||||
))
|
||||
}
|
||||
|
||||
return schoolList
|
||||
}
|
||||
|
||||
internal fun getExtractedIdFromUrl(snpPageUrl: String): String {
|
||||
val path = snpPageUrl.split(client.host).getOrNull(1)?.split("/")
|
||||
|
||||
if (6 != path?.size) {
|
||||
logger.error("Expected snp url, got {}", snpPageUrl)
|
||||
throw VulcanException("Na pewno używasz konta z dostępem do Witryny ucznia i rodzica?")
|
||||
}
|
||||
|
||||
return path[2]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package io.github.wulkanowy.api.login;
|
||||
|
||||
public class VulcanOfflineException extends Exception {
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -0,0 +1,33 @@
|
||||
package io.github.wulkanowy.api.mobile
|
||||
|
||||
import io.github.wulkanowy.api.SnP
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class RegisterDevice(private val snp: SnP) {
|
||||
|
||||
companion object {
|
||||
const val REGISTER_URL = "DostepMobilny.mvc/Rejestruj"
|
||||
}
|
||||
|
||||
data class Token(
|
||||
val token: String,
|
||||
val symbol: String,
|
||||
val pin: String
|
||||
)
|
||||
|
||||
fun getToken(): Token {
|
||||
val form = snp.getSnPPageDocument(REGISTER_URL).selectFirst("#rejestracja-formularz")
|
||||
|
||||
val fields = form.select(".blockElement")
|
||||
|
||||
return Token(
|
||||
getValue(fields[1]),
|
||||
getValue(fields[2]),
|
||||
getValue(fields[3])
|
||||
)
|
||||
}
|
||||
|
||||
fun getValue(e: Element): String {
|
||||
return e.text().split(":")[1].trim()
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package io.github.wulkanowy.api.mobile
|
||||
|
||||
import io.github.wulkanowy.api.SnP
|
||||
import io.github.wulkanowy.api.getFormattedDate
|
||||
|
||||
class RegisteredDevices(private val snp: SnP) {
|
||||
|
||||
companion object {
|
||||
const val DEVICES_LIST_URL = "DostepMobilny.mvc"
|
||||
}
|
||||
|
||||
data class Device(
|
||||
val name: String,
|
||||
val system: String,
|
||||
val date: String,
|
||||
val id: Int
|
||||
)
|
||||
|
||||
fun getList(): List<Device> {
|
||||
val items = snp.getSnPPageDocument(DEVICES_LIST_URL).select("table tbody tr")
|
||||
val devices: MutableList<Device> = mutableListOf()
|
||||
|
||||
for (item in items) {
|
||||
val cells = item.select("td")
|
||||
val system = cells[0].text().split("(").last().removeSuffix(")")
|
||||
|
||||
devices.add(Device(
|
||||
cells[0].text().replace(" ($system)", ""),
|
||||
system,
|
||||
getFormattedDate(cells[1].text(), "dd.MM.yyyy 'godz:' HH:mm:ss", "yyyy-MM-dd HH:mm:ss"),
|
||||
cells[2].select("a").attr("href")
|
||||
.split("/").last().toInt()
|
||||
))
|
||||
}
|
||||
|
||||
return devices
|
||||
}
|
||||
}
|
@ -8,24 +8,25 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.api.SnP;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
|
||||
public class AchievementsList {
|
||||
|
||||
private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie";
|
||||
|
||||
private SnP snp = null;
|
||||
|
||||
private List<String> achievements = new ArrayList<>();
|
||||
private SnP snp;
|
||||
|
||||
public AchievementsList(SnP snp) {
|
||||
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");
|
||||
|
||||
List<String> achievements = new ArrayList<>();
|
||||
|
||||
for (Element item : items) {
|
||||
achievements.add(item.text());
|
||||
}
|
||||
|
@ -8,29 +8,32 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.api.SnP;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
|
||||
|
||||
public class NotesList {
|
||||
|
||||
private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie";
|
||||
|
||||
private SnP snp = null;
|
||||
|
||||
private List<Note> notes = new ArrayList<>();
|
||||
private SnP snp;
|
||||
|
||||
public NotesList(SnP snp) {
|
||||
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");
|
||||
Elements dates = pageFragment.select("h2");
|
||||
|
||||
List<Note> notes = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
for (Element item : items) {
|
||||
notes.add(new Note()
|
||||
.setDate(dates.get(index++).text())
|
||||
.setDate(getFormattedDate(dates.get(index++).text()))
|
||||
.setTeacher(snp.getRowDataChildValue(item, 1))
|
||||
.setCategory(snp.getRowDataChildValue(item, 2))
|
||||
.setContent(snp.getRowDataChildValue(item, 3))
|
||||
|
@ -5,18 +5,19 @@ import org.jsoup.nodes.Element;
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.api.SnP;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
|
||||
public class SchoolInfo {
|
||||
|
||||
private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele";
|
||||
|
||||
private SnP snp = null;
|
||||
private SnP snp;
|
||||
|
||||
public SchoolInfo(SnP snp) {
|
||||
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);
|
||||
|
||||
|
@ -9,18 +9,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.api.SnP;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
|
||||
public class TeachersInfo {
|
||||
|
||||
private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele";
|
||||
|
||||
private SnP snp = null;
|
||||
private SnP snp;
|
||||
|
||||
public TeachersInfo(SnP snp) {
|
||||
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();
|
||||
|
@ -3,60 +3,64 @@ package io.github.wulkanowy.api.timetable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.generic.Day;
|
||||
import io.github.wulkanowy.api.VulcanException;
|
||||
import io.github.wulkanowy.api.generic.Lesson;
|
||||
import io.github.wulkanowy.api.generic.Week;
|
||||
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
|
||||
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
|
||||
|
||||
public class Timetable {
|
||||
|
||||
private static final String TIMETABLE_PAGE_URL = "Lekcja.mvc/PlanLekcji?data=";
|
||||
private static final String TIMETABLE_PAGE_URL = "Lekcja.mvc/PlanZajec?data=";
|
||||
|
||||
private SnP snp;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Timetable.class);
|
||||
|
||||
public Timetable(SnP snp) {
|
||||
this.snp = snp;
|
||||
}
|
||||
|
||||
public Week<Day> getWeekTable() throws IOException, ParseException {
|
||||
public Week<TimetableDay> getWeekTable() throws IOException, VulcanException {
|
||||
return getWeekTable("");
|
||||
}
|
||||
|
||||
public Week<Day> getWeekTable(final String tick) throws IOException, ParseException {
|
||||
Element table = snp.getSnPPageDocument(TIMETABLE_PAGE_URL + tick)
|
||||
public Week<TimetableDay> getWeekTable(final String date) throws IOException, VulcanException {
|
||||
Element table = snp.getSnPPageDocument(TIMETABLE_PAGE_URL + getDateAsTick(date))
|
||||
.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) {
|
||||
List<TimetableDay> days = new ArrayList<>();
|
||||
int numberOfDays = tableHeaderCells.size();
|
||||
|
||||
for (int i = 2; i < 7; i++) {
|
||||
if (numberOfDays > 7) {
|
||||
logger.info("Number of days: {}", numberOfDays);
|
||||
}
|
||||
|
||||
for (int i = 2; i < numberOfDays; i++) {
|
||||
String[] dayHeaderCell = tableHeaderCells.get(i).html().split("<br>");
|
||||
|
||||
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();
|
||||
TimetableDay day = new TimetableDay();
|
||||
day.setDayName(dayHeaderCell[0]);
|
||||
day.setDate(sdf.format(d));
|
||||
day.setDate(getFormattedDate(dayHeaderCell[1].trim()));
|
||||
|
||||
if (tableHeaderCells.get(i).hasClass("free-day")) {
|
||||
day.setFreeDay(true);
|
||||
@ -69,7 +73,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");
|
||||
|
||||
@ -81,7 +85,7 @@ public class Timetable {
|
||||
lesson.setStartTime(startEndEnd[0]);
|
||||
lesson.setEndTime(startEndEnd[1]);
|
||||
lesson.setDate(days.get(i - 2).getDate());
|
||||
lesson.setNumber(hours.get(0).text());
|
||||
lesson.setNumber(Integer.valueOf(hours.get(0).text()));
|
||||
|
||||
addLessonDetails(lesson, hours.get(i).select("div"));
|
||||
|
||||
@ -98,7 +102,16 @@ public class Timetable {
|
||||
addLessonInfoFromElement(lesson, e.first());
|
||||
break;
|
||||
case 2:
|
||||
addLessonInfoFromElement(lesson, e.last());
|
||||
Element span = e.last().selectFirst("span");
|
||||
if (null == span) {
|
||||
addLessonInfoFromElement(lesson, e.first());
|
||||
} else if (span.hasClass(LessonTypes.CLASS_MOVED_OR_CANCELED)) {
|
||||
lesson.setNewMovedInOrChanged(true);
|
||||
lesson.setDescription("poprzednio: " + getLessonAndGroupInfoFromSpan(span)[0]);
|
||||
addLessonInfoFromElement(lesson, e.first());
|
||||
} else {
|
||||
addLessonInfoFromElement(lesson, e.last());
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
addLessonInfoFromElement(lesson, e.get(1));
|
||||
@ -113,7 +126,9 @@ public class Timetable {
|
||||
Elements warn = e.select(".uwaga-panel");
|
||||
|
||||
if (!warn.isEmpty()) {
|
||||
e.select(".x-treelabel-rlz").last().text("(" + warn.text() + ")");
|
||||
e.select("span").last()
|
||||
.addClass("x-treelabel-rlz")
|
||||
.text(warn.text());
|
||||
e.remove(1);
|
||||
}
|
||||
}
|
||||
@ -121,6 +136,11 @@ public class Timetable {
|
||||
private void addLessonInfoFromElement(Lesson lesson, Element e) {
|
||||
Elements spans = e.select("span");
|
||||
|
||||
if (spans.isEmpty()) {
|
||||
logger.warn("Lesson span is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
addTypeInfo(lesson, spans);
|
||||
addNormalLessonInfo(lesson, spans);
|
||||
addChangesInfo(lesson, spans);
|
||||
@ -164,7 +184,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 +196,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()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,12 +227,17 @@ public class Timetable {
|
||||
}
|
||||
|
||||
private String[] getLessonAndGroupInfoFromSpan(Element span) {
|
||||
if (!span.text().contains("[")) {
|
||||
return new String[] {span.text(), ""};
|
||||
}
|
||||
|
||||
String[] subjectNameArray = span.text().split(" ");
|
||||
String groupName = subjectNameArray[subjectNameArray.length - 1];
|
||||
|
||||
return new String[]{
|
||||
span.text().replace(" " + groupName, ""),
|
||||
StringUtils.substringBetween(groupName, "[", "]")
|
||||
StringUtils.defaultString(StringUtils.substringBetween(
|
||||
groupName, "[", "]"), groupName)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
@ -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)");
|
||||
|
||||
|
78
api/src/test/java/io/github/wulkanowy/api/ClientTest.java
Normal file
78
api/src/test/java/io/github/wulkanowy/api/ClientTest.java
Normal file
@ -0,0 +1,78 @@
|
||||
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() {
|
||||
Client client = new Client("http://fakelog.cf\\\\admin", "pass", "Default", "123");
|
||||
|
||||
Assert.assertEquals("fakelog.cf", client.getHost());
|
||||
Assert.assertEquals("Default", client.getSymbol());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setFullEndpointInfoWithSymbolTest() {
|
||||
Client client = new Client("http://fakelog.cf/notdefault\\\\admin", "pass", "Default", "123");
|
||||
|
||||
Assert.assertEquals("fakelog.cf", client.getHost());
|
||||
Assert.assertEquals("notdefault", client.getSymbol()); //
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForNoErrorsTest() throws Exception {
|
||||
Client client = new Client("", "", "", "123");
|
||||
|
||||
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-success.html"));
|
||||
|
||||
Assert.assertEquals(doc, client.checkForErrors(doc, 200));
|
||||
}
|
||||
|
||||
@Test(expected = VulcanOfflineException.class)
|
||||
public void checkForErrorsOffline() throws Exception {
|
||||
Client client = new Client("", "", "", "123");
|
||||
|
||||
Document doc = Jsoup.parse(getFixtureAsString("login/PrzerwaTechniczna.html"));
|
||||
|
||||
client.checkForErrors(doc, 200);
|
||||
}
|
||||
|
||||
@Test(expected = NotLoggedInErrorException.class)
|
||||
public void checkForErrors() throws Exception {
|
||||
Client client = new Client("", "", "", "123");
|
||||
|
||||
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-notLoggedIn.html"));
|
||||
|
||||
client.checkForErrors(doc, 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFilledUrlTest() throws Exception {
|
||||
Client client = new Client("http://fakelog.cf\\\\admin", "", "symbol123", "321");
|
||||
|
||||
Assert.assertEquals("http://uonetplus-opiekun.fakelog.cf/symbol123/321/Oceny/Wszystkie",
|
||||
client.getFilledUrl("{schema}://uonetplus-opiekun.{host}/{symbol}/{ID}/Oceny/Wszystkie"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSymbolTest() {
|
||||
Client client = new Client("", "", "symbol4321", "123");
|
||||
|
||||
Assert.assertEquals("symbol4321", client.getSymbol());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSchoolIdTest() throws Exception {
|
||||
Client client = new Client("", "", "1", "123456");
|
||||
|
||||
Assert.assertEquals("123456", client.getSchoolId());
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package io.github.wulkanowy.api
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class DateTimeUtilsTest {
|
||||
|
||||
@Test
|
||||
fun getTicksDateObjectTest() {
|
||||
val format = SimpleDateFormat("dd.MM.yyyy", Locale.ROOT)
|
||||
format.timeZone = TimeZone.getTimeZone("UTC")
|
||||
val date = format.parse("31.07.2017")
|
||||
|
||||
Assert.assertEquals(636370560000000000L, getDateAsTick(date))
|
||||
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.time = date
|
||||
calendar.add(Calendar.DAY_OF_YEAR, -14)
|
||||
val dateTwoWeekBefore = calendar.time
|
||||
|
||||
Assert.assertEquals(636358464000000000L, getDateAsTick(dateTwoWeekBefore))
|
||||
}
|
||||
|
||||
@Test(expected = ParseException::class)
|
||||
fun getTicsStringInvalidFormatTest() {
|
||||
Assert.assertEquals(636370560000000000L, getDateAsTick("31.07.2017", "dd.MMM.yyyy"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getTicsStringFormatTest() {
|
||||
Assert.assertEquals(636370560000000000L, getDateAsTick("31.07.2017", "dd.MM.yyyy"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getTicsStringTest() {
|
||||
Assert.assertEquals("636370560000000000", getDateAsTick("2017-07-31"))
|
||||
Assert.assertEquals("636334272000000000", getDateAsTick("2017-06-19"))
|
||||
Assert.assertEquals("636189120000000000", getDateAsTick("2017-01-02"))
|
||||
Assert.assertEquals("636080256000000000", getDateAsTick("2016-08-29"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDateTest() {
|
||||
val format = SimpleDateFormat("dd.MM.yyyy", Locale.ROOT)
|
||||
format.timeZone = TimeZone.getTimeZone("UTC")
|
||||
val date = format.parse("31.07.2017")
|
||||
|
||||
Assert.assertEquals(date, getDate(636370560000000000L))
|
||||
}
|
||||
}
|
@ -7,10 +7,11 @@ 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;
|
||||
import io.github.wulkanowy.api.generic.Semester;
|
||||
|
||||
public class StudentAndParentTest {
|
||||
|
||||
@ -24,102 +25,79 @@ 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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSnpPageUrlWithIdTest() throws Exception {
|
||||
Assert.assertEquals("{schema}://uonetplus-opiekun.{host}/{symbol}/123456/",
|
||||
(new StudentAndParent(client, "123456")).getSnpHomePageUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSnpPageUrlWithoutIdTest() throws Exception {
|
||||
String input = FixtureHelper.getAsString(getClass().getResourceAsStream("Start.html"));
|
||||
Document startPageDocument = Jsoup.parse(input);
|
||||
|
||||
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
|
||||
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(startPageDocument);
|
||||
StudentAndParent snp = new StudentAndParent(client);
|
||||
|
||||
Assert.assertEquals("https://uonetplus-opiekun.vulcan.net.pl/symbol/534213/Start/Index/",
|
||||
snp.getSnpHomePageUrl());
|
||||
}
|
||||
|
||||
@Test(expected = NotLoggedInErrorException.class)
|
||||
public void getSnpPageUrlWithWrongPage() throws Exception {
|
||||
Document wrongPageDocument = Jsoup.parse(
|
||||
FixtureHelper.getAsString(getClass().getResourceAsStream("OcenyWszystkie-semester.html"))
|
||||
);
|
||||
|
||||
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(wrongPageDocument);
|
||||
StudentAndParent snp = new StudentAndParent(client);
|
||||
|
||||
snp.getSnpHomePageUrl();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExtractedIDStandardTest() throws Exception {
|
||||
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
|
||||
StudentAndParent snp = new StudentAndParent(client, "symbol");
|
||||
Assert.assertEquals("123456", snp.getExtractedIdFromUrl("https://uonetplus-opiekun"
|
||||
+ ".vulcan.net.pl/powiat/123456/Start/Index/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExtractedIDDemoTest() throws Exception {
|
||||
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
|
||||
StudentAndParent snp = new StudentAndParent(client, "symbol");
|
||||
Assert.assertEquals("demo12345",
|
||||
snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
|
||||
}
|
||||
|
||||
@Test(expected = NotLoggedInErrorException.class)
|
||||
public void getExtractedIDNotLoggedTest() throws Exception {
|
||||
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
|
||||
StudentAndParent snp = new StudentAndParent(client, "symbol");
|
||||
Assert.assertEquals("123",
|
||||
snp.getExtractedIdFromUrl("https://uonetplus.vulcan.net.pl/powiat/"));
|
||||
public void snpTest() {
|
||||
StudentAndParent snp = new StudentAndParent(client, "1234", null);
|
||||
Assert.assertEquals("1234", snp.getStudentID());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSemestersTest() throws Exception {
|
||||
SnP snp = new StudentAndParent(client, "123456");
|
||||
SnP snp = new StudentAndParent(client, 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 {
|
||||
String input = FixtureHelper.getAsString(getClass().getResourceAsStream("WitrynaUczniaIRodzica.html"));
|
||||
Document snpHome = Jsoup.parse(input);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import io.github.wulkanowy.api.generic.Semester;
|
||||
|
||||
public abstract class StudentAndParentTestCase {
|
||||
|
||||
protected StudentAndParent getSnp(String fixtureFileName) throws Exception {
|
||||
@ -16,7 +18,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();
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ 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
|
||||
public void getSubjectTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("Zajęcia z wychowawcą", list.get(0).getSubject());
|
||||
Assert.assertEquals("Język angielski", list.get(3).getSubject());
|
||||
@ -34,7 +34,7 @@ public class GradesListTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getValueTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("5", list.get(0).getValue());
|
||||
Assert.assertEquals("5", list.get(3).getValue());
|
||||
@ -44,7 +44,7 @@ public class GradesListTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getColorTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("000000", list.get(0).getColor());
|
||||
Assert.assertEquals("1289F7", list.get(3).getColor());
|
||||
@ -54,27 +54,29 @@ public class GradesListTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getSymbolTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("A1", list.get(0).getSymbol());
|
||||
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
|
||||
public void getDescriptionTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("Dzień Kobiet w naszej klasie", list.get(0).getDescription());
|
||||
Assert.assertEquals("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
|
||||
public void getWeightTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("1,00", list.get(0).getWeight());
|
||||
Assert.assertEquals("3,00", list.get(3).getWeight());
|
||||
@ -84,7 +86,7 @@ public class GradesListTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getDateTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("2017-03-21", list.get(0).getDate());
|
||||
Assert.assertEquals("2017-06-02", list.get(3).getDate());
|
||||
@ -94,21 +96,11 @@ public class GradesListTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getTeacherTest() throws Exception {
|
||||
List<Grade> list = filled.getAll();
|
||||
List<Grade> list = filled.getAll("");
|
||||
|
||||
Assert.assertEquals("Patryk Maciejewski", list.get(0).getTeacher());
|
||||
Assert.assertEquals("Oliwia Woźniak", list.get(3).getTeacher());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -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,121 @@ 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();
|
||||
Mockito.when(client.getHost()).thenReturn("fakelog.cf");
|
||||
Login login = new Login(client);
|
||||
login.login("a@a", "pswd", "d123");
|
||||
|
||||
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
|
||||
Assert.assertEquals("d123", client.getSymbol());
|
||||
}
|
||||
|
||||
@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();
|
||||
Mockito.when(client.getHost()).thenReturn("fakelog.cf");
|
||||
Login login = new Login(client);
|
||||
|
||||
Assert.assertEquals("wulkanowyschool321",
|
||||
login.sendCertificate("", "wulkanowyschool321"));
|
||||
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "wulkanowyschool321");
|
||||
|
||||
Assert.assertEquals("wulkanowyschool321", client.getSymbol());
|
||||
}
|
||||
|
||||
@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();
|
||||
Mockito.when(client.getHost()).thenReturn("fakelog.cf");
|
||||
Login login = new Login(client);
|
||||
|
||||
Assert.assertEquals("demo12345",
|
||||
login.sendCertificate(getFixtureAsString("cert.xml"), "Default"));
|
||||
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default");
|
||||
|
||||
Assert.assertEquals("demo12345", client.getSymbol());
|
||||
}
|
||||
|
||||
@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"));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
package io.github.wulkanowy.api.login
|
||||
|
||||
import io.github.wulkanowy.api.Client
|
||||
import io.github.wulkanowy.api.FixtureHelper
|
||||
import io.github.wulkanowy.api.VulcanException
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.mock
|
||||
|
||||
class StartPageTest {
|
||||
|
||||
private val client: Client = mock(Client::class.java)
|
||||
|
||||
@Before fun setUp() {
|
||||
Mockito.`when`(client.host).thenReturn("fakelog.cf")
|
||||
}
|
||||
|
||||
private fun getDoc(name: String): Document = Jsoup.parse(FixtureHelper.getAsString(javaClass.getResourceAsStream(name)))
|
||||
|
||||
@Test fun getSchoolTest() {
|
||||
assertEquals("534213", StartPage(client).getSchools(getDoc("../Start-std.html"))[0].id)
|
||||
}
|
||||
|
||||
@Test fun getMultiSchoolTest() {
|
||||
val schools = StartPage(client).getSchools(getDoc("../Start-multi.html"))
|
||||
|
||||
assertEquals("123456", schools[0].id)
|
||||
assertEquals("123457", schools[1].id)
|
||||
}
|
||||
|
||||
@Test fun getSchoolNameTest() {
|
||||
assertEquals("Uczeń", StartPage(client).getSchools(getDoc("../Start-std.html"))[0].name)
|
||||
}
|
||||
|
||||
@Test fun getMultiSchoolNameTest() {
|
||||
val schools = StartPage(client).getSchools(getDoc("../Start-multi.html"))
|
||||
|
||||
assertEquals("GIMBB", schools[0].name)
|
||||
assertEquals("SPBB", schools[1].name)
|
||||
}
|
||||
|
||||
@Test(expected = VulcanException::class)
|
||||
fun getSnpPageUrlWithWrongPage() {
|
||||
StartPage(client).getSchools(getDoc("../OcenyWszystkie-semester.html"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getExtractedIDStandardTest() {
|
||||
assertEquals("123456", StartPage(client)
|
||||
.getExtractedIdFromUrl("https://uonetplus-opiekun.fakelog.cf/powiat/123456/Start/Index/"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getExtractedIDDemoTest() {
|
||||
assertEquals("demo12345", StartPage(client)
|
||||
.getExtractedIdFromUrl("https://uonetplus-opiekun.fakelog.cf/demoupowiat/demo12345/Start/Index/"))
|
||||
}
|
||||
|
||||
@Test(expected = VulcanException::class)
|
||||
fun getExtractedIDNotLoggedTest() {
|
||||
assertEquals("123", StartPage(client)
|
||||
.getExtractedIdFromUrl("https://uonetplus.NOTfakelog.cf/powiat/"))
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
package io.github.wulkanowy.api.mobile
|
||||
|
||||
import io.github.wulkanowy.api.StudentAndParentTestCase
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class RegisterDeviceTest : StudentAndParentTestCase() {
|
||||
|
||||
@Test
|
||||
fun getTokenTest() {
|
||||
val registration = RegisterDevice(getSnp("Rejestruj.html"))
|
||||
|
||||
assertEquals("3S1A1B2C", registration.getToken().token)
|
||||
assertEquals("Default", registration.getToken().symbol)
|
||||
assertEquals("1234567", registration.getToken().pin)
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package io.github.wulkanowy.api.mobile
|
||||
|
||||
import io.github.wulkanowy.api.StudentAndParentTestCase
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class RegisteredDevicesListTest : StudentAndParentTestCase() {
|
||||
|
||||
private val filled = RegisteredDevices(getSnp("DostepMobilny-filled.html"))
|
||||
|
||||
@Test
|
||||
fun getListTest() {
|
||||
assertEquals(2, filled.getList().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNameTest() {
|
||||
assertEquals("google Android SDK built for x86", filled.getList()[0].name)
|
||||
assertEquals("google (Android SDK) built for x86", filled.getList()[1].name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSystemTest() {
|
||||
assertEquals("Android 8.1.0", filled.getList()[0].system)
|
||||
assertEquals("Android 8.1.0", filled.getList()[1].system)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDateTest() {
|
||||
assertEquals("2018-01-20 22:35:30", filled.getList()[0].date)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getIdTest() {
|
||||
assertEquals(321, filled.getList()[0].id)
|
||||
}
|
||||
}
|
@ -30,8 +30,8 @@ public class NotesListTest extends StudentAndParentTestCase {
|
||||
public void getDateTest() throws Exception {
|
||||
List<Note> filledList = filled.getAllNotes();
|
||||
|
||||
Assert.assertEquals("06.06.2017", filledList.get(0).getDate());
|
||||
Assert.assertEquals("01.10.2016", filledList.get(2).getDate());
|
||||
Assert.assertEquals("2017-06-06", filledList.get(0).getDate());
|
||||
Assert.assertEquals("2016-10-01", filledList.get(2).getDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -83,11 +83,11 @@ public class TimetableTest extends StudentAndParentTestCase {
|
||||
|
||||
@Test
|
||||
public void getLessonNumberTest() throws Exception {
|
||||
Assert.assertEquals("2", std.getWeekTable().getDay(0).getLesson(1).getNumber());
|
||||
Assert.assertEquals("5", std.getWeekTable().getDay(2).getLesson(4).getNumber());
|
||||
Assert.assertEquals("0", full.getWeekTable().getDay(0).getLesson(0).getNumber());
|
||||
Assert.assertEquals("13", full.getWeekTable().getDay(4).getLesson(13).getNumber());
|
||||
Assert.assertEquals("3", holidays.getWeekTable().getDay(3).getLesson(3).getNumber());
|
||||
Assert.assertEquals(2, std.getWeekTable().getDay(0).getLesson(1).getNumber());
|
||||
Assert.assertEquals(5, std.getWeekTable().getDay(2).getLesson(4).getNumber());
|
||||
Assert.assertEquals(0, full.getWeekTable().getDay(0).getLesson(0).getNumber());
|
||||
Assert.assertEquals(13, full.getWeekTable().getDay(4).getLesson(13).getNumber());
|
||||
Assert.assertEquals(3, holidays.getWeekTable().getDay(3).getLesson(3).getNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -105,11 +105,13 @@ public class TimetableTest extends StudentAndParentTestCase {
|
||||
Assert.assertEquals("Zajęcia techniczne", std.getWeekTable().getDay(2).getLesson(4).getSubject());
|
||||
Assert.assertEquals("Wychowanie fizyczne", std.getWeekTable().getDay(1).getLesson(1).getSubject());
|
||||
Assert.assertEquals("Język angielski", full.getWeekTable().getDay(0).getLesson(1).getSubject());
|
||||
Assert.assertEquals("Wychowanie fizyczne", full.getWeekTable().getDay(0).getLesson(9).getSubject());
|
||||
Assert.assertEquals("Wychowanie do życia w rodzinie", full.getWeekTable().getDay(2).getLesson(0).getSubject());
|
||||
Assert.assertEquals("Wychowanie fizyczne", full.getWeekTable().getDay(3).getLesson(1).getSubject());
|
||||
Assert.assertEquals("Uroczyste zakończenie roku szkolnego", full.getWeekTable().getDay(4).getLesson(0).getSubject());
|
||||
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 +124,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 +151,13 @@ public class TimetableTest extends StudentAndParentTestCase {
|
||||
Assert.assertEquals("zastępstwo (poprzednio: Religia)", full.getWeekTable().getDay(2).getLesson(0).getDescription());
|
||||
Assert.assertEquals("zastępstwo (poprzednio: 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("poprzednio: Zajęcia z wychowawcą", full.getWeekTable().getDay(4).getLesson(5).getDescription());
|
||||
Assert.assertEquals("opis w uwadze bez klasy w spanie", full.getWeekTable().getDay(4).getLesson(4).getDescription());
|
||||
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getDescription());
|
||||
}
|
||||
|
||||
@ -237,6 +246,8 @@ public class TimetableTest extends StudentAndParentTestCase {
|
||||
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(2).isNewMovedInOrChanged());
|
||||
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(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());
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Uonet+</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="startScreen">
|
||||
<div class="holder">
|
||||
<div class="content">
|
||||
<div class="panel linkownia pracownik klient">
|
||||
<div id="idAppUczen" class="subDiv">
|
||||
<a href="https://uonetplus-opiekun.fakelog.cf/symbol/123456/Start/Index/">
|
||||
<span class="header directLink">GIMBB</span>
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://uonetplus-opiekun.fakelog.cf/symbol/123457/Start/Index/">
|
||||
<span class="header directLink">SPBB</span>
|
||||
</a>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -9,7 +9,7 @@
|
||||
<div class="holder">
|
||||
<div class="content">
|
||||
<div class="panel linkownia pracownik klient">
|
||||
<a href="https://uonetplus-opiekun.vulcan.net.pl/symbol/534213/Start/Index/">
|
||||
<a href="https://uonetplus-opiekun.fakelog.cf/symbol/534213/Start/Index/">
|
||||
<div class="imagedHeader directLink">
|
||||
<div id="idEmptyAppUczeń">
|
||||
<div class="name">Uczeń</div>
|
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Witryna ucznia i rodzica – Strona głó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?&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?&id=1300">
|
||||
3Ti 2017
|
||||
</option>
|
||||
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&id=1200">
|
||||
2Ti 2016
|
||||
</option>
|
||||
<option value="https://uonetplus-opiekun.fakelog.cf/Default/123456/Dziennik/DziennikOnChange?&id=1100">
|
||||
1Ti 2015
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<footer>wersja: 17.09.0008.26553</footer>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Witryna ucznia i rodzica – Terminarz sprawdzianów</title>
|
||||
</head>
|
||||
<body>
|
||||
<main class="mainContainer">
|
||||
<h1>Sprawdziany</h1>
|
||||
<h2>Tydzień 30.04.2018 - 06.05.2018</h2>
|
||||
<h2>Nie zaplanowano żadnych sprawdzianów na wybrany tydzień</h2>
|
||||
<div class="navigation">
|
||||
<a href="/symbol/123456/Sprawdziany.mvc/Terminarz?data=636600384000000000&rokSzkolny=2017&rodzajWidoku=2" class="button-prev">Poprzedni tydzień</a>
|
||||
<a href="/symbol/123456/Sprawdziany.mvc/Terminarz?data=636612480000000000&rokSzkolny=2017&rodzajWidoku=2" class="button-next">Następny tydzień</a>
|
||||
</div>
|
||||
</main>
|
||||
<footer>wersja: 17.09.0009.26859</footer>
|
||||
</body>
|
||||
</html>
|
@ -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>
|
||||
|
@ -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="http://docs.oasis-open.org/ws-sx/ws-trust/200512"><trust:RequestSecurityTokenResponse Context="https://uonetplus.fake-log.com/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: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="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: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">
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -11,6 +11,19 @@
|
||||
<span class="userdata">example@wulkanowy.io (<a href="/demo123/LoginEndpoint.aspx?logout=true">wyloguj</a>)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="holder">
|
||||
<div class="content">
|
||||
<div class="panel linkownia pracownik klient">
|
||||
<a href="https://uonetplus-opiekun.fakelog.cf/symbol/534213/Start/Index/">
|
||||
<div class="imagedHeader directLink">
|
||||
<div id="idEmptyAppUczeń">
|
||||
<div class="name">Uczeń</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -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>
|
@ -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>
|
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Witryna ucznia i rodzica – dostęp mobilny</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main class="mainContainer">
|
||||
<h1>Dostęp mobilny</h1>
|
||||
|
||||
<article>
|
||||
<h2>Zarejestrowane urządzenia</h2>
|
||||
</article>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Urządzenie</th>
|
||||
<th>Data rejestracji</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="text-center">
|
||||
<td>google Android SDK built for x86 (Android 8.1.0)</td>
|
||||
<td>20.01.2018 godz: 22:35:30</td>
|
||||
<td class="cellWithButton">
|
||||
<a href="/Default/123456/DostepMobilny.mvc/Wyrejestruj/321" class="button">Wyrejestruj</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="text-center">
|
||||
<td>google (Android SDK) built for x86 (Android 8.1.0)</td>
|
||||
<td>20.01.2018 godz: 22:35:30</td>
|
||||
<td class="cellWithButton">
|
||||
<a href="/Default/123456/DostepMobilny.mvc/Wyrejestruj/213" class="button">Wyrejestruj</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</main>
|
||||
|
||||
<footer>wersja: 18.01.0001.27311</footer>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Witryna ucznia i rodzica – Rejestracja urządzenia mobilnego</title>
|
||||
<style>
|
||||
.blockElement {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="mainContainer">
|
||||
<h1>Rejestracja urządzenia mobilnego</h1>
|
||||
<article class="text-center" id="rejestracja-formularz">
|
||||
<span class="blockElement">Za pomocą aplikacji "Dzienniczek+" zeskanuj kod QR.</span>
|
||||
<img src=" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gUdCTohm9rlswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAFKklEQVR42u3dYYqDQAyA0abk/lfO/l+6LLZYksx7J3C09SPgaFRVPQDgoqdTAICAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAFdltwOKiNUnvKqOXj/4/9y3fhMIACMICAACAoCAACAgAAgIAAgIAJ/IaQfc7Tno3+5+Dr37+sH/p+/6TSAACAgAAgKAgACAgAAgIAAICADj5bYF2YcBuH+YQAAQEAAEBAAEBAABAUBAABAQAAQEAAQEAAEBQEAAEBAABAQABAQAAQFAQAAQEAAEBAAEBAABAUBAABAQAAQEAP6R2xZUVa4q4P5hAgFAQAAQEAAQEAAEBAABAUBAANho3D6QiHDVAPcPEwgAAgKAgACAgAAgIAAICAACAsCJ2u0D8T5+wP3DBAKAgACAgAAgIAAICAACAoCAAMBL7faBeF8/4P7wWrd9LiYQAAQEAAEBQEAAEBAAEBAABASAr8tpB+x9/7DX6f/vaftcTCAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIA4BQAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAANBWTjvgiDj6glWVXy1gAgFAQAAQEAAQEAAEBAABAUBAuOb0x5CBPdrtAzl9n4PAACYQAAQEAAQEAAEBQEAAEBAABAQA/tBuH8j2fRC+5wGYQAAQEAAQEAAEBAABAUBAAEBAAHhTTjvg7vsofM8DMIEAgIAAICAACAgAAgKAgACAgABwk9y2oLv3YfieB4AJBAABAUBAABAQAAQEAAQEAAEBQEAAEBAABAQABAQAAQFAQAAQEAAEBAAEBAABAUBAABAQAAQEAAQEAAEBQEAAGC+3LaiqXFUAEwgAAgKAgACAgAAgIAAICAACAsBG4/aBRMTRF+z09QMmEAAEBAABAQABAUBAABAQAAQEgINF+YAGACYQAAQEAAEBQEAAQEAAEBAABAQAAQFAQABAQAAQEAAEBAABAUBAAEBAABAQAAQEAAEBQEAAQEAAEBAABAQAAQFAQABAQAAQEAAEBAABAUBAAEBAABAQAAQEAAEBQEAAQEAA+IYf8fZKNX0RrMQAAAAASUVORK5CYII="
|
||||
alt="Kod QR" title="Kod QR" height="400" width="400"/>
|
||||
<span class="blockElement">Token: 3S1A1B2C</span>
|
||||
<span class="blockElement">Symbol: Default</span>
|
||||
<span class="blockElement">PIN: 1234567</span>
|
||||
</article>
|
||||
</main>
|
||||
<footer>wersja: 18.01.0001.27311</footer>
|
||||
</body>
|
||||
</html>
|
@ -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>
|
||||
@ -251,7 +319,16 @@
|
||||
<span></span>
|
||||
</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">Język polski</span>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv"> </span>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">16</span>
|
||||
<span class="random-class">(oddział nieobecny)</span>
|
||||
</div>
|
||||
<button type="button" class="uwaga-btn">Uwaga</button>
|
||||
<div class="uwaga-panel">opis w uwadze bez klasy w spanie</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td>
|
||||
@ -287,7 +364,20 @@
|
||||
<span></span>
|
||||
</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="">Tworzenie i administrowanie bazami danych [zaw2]</span>
|
||||
<span class=""></span>
|
||||
<span class=""></span>
|
||||
<span class=""></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">Zajęcia z wychowawcą</span>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">Małgorzata Kowal</span>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">43</span>
|
||||
<span class="x-treelabel-rlz">(zmiana organizacji zajęć)</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
@ -393,7 +483,18 @@
|
||||
<tr>
|
||||
<td>9</td>
|
||||
<td>14:50 15:35</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="x-treelabel-ppl x-treelabel-zas">Wychowanie fizyczne [zaw2]</span>
|
||||
<span class="x-treelabel-ppl x-treelabel-zas"></span>
|
||||
<span class="x-treelabel-ppl x-treelabel-zas"></span>
|
||||
<span class="x-treelabel-ppl x-treelabel-zas">G3</span>
|
||||
<span class="x-treelabel-rlz">(przeniesiona z lekcji 7, 01.12.2017)</span>
|
||||
</div>
|
||||
<div>
|
||||
<!--<span>WTF</span>-->
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="x-treelabel-ppl x-treelabel-inv">Język niemiecki [J1]</span>
|
||||
|
118
app/build.gradle
118
app/build.gradle
@ -1,12 +1,25 @@
|
||||
apply plugin: 'org.greenrobot.greendao'
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt' // sync warning probably caused by bug https://issuetracker.google.com/issues/74537216
|
||||
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'
|
||||
|
||||
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:$playPublisher"
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,35 +27,50 @@ repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'org.greenrobot.greendao'
|
||||
apply plugin: 'io.fabric'
|
||||
apply from: '../jacoco.gradle'
|
||||
apply from: '../android-sonarqube.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion "27.0.3"
|
||||
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 1
|
||||
versionName "0.1.0"
|
||||
versionCode 15
|
||||
versionName "0.5.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 +87,58 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
play {
|
||||
track = 'alpha'
|
||||
uploadImages = true
|
||||
}
|
||||
|
||||
greendao {
|
||||
schemaVersion 20
|
||||
schemaVersion 29
|
||||
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 "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
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.jakewharton.timber:timber:$timber"
|
||||
implementation "at.favre.lib:slf4j-timber:$slf4jTimber"
|
||||
|
||||
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'
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger2"
|
||||
kapt "com.google.dagger:dagger-android-processor:$dagger2"
|
||||
kapt "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"
|
||||
|
||||
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"
|
||||
}
|
||||
|
56
app/jacoco.gradle
Normal file
56
app/jacoco.gradle
Normal file
@ -0,0 +1,56 @@
|
||||
apply plugin: "jacoco"
|
||||
|
||||
jacoco {
|
||||
toolVersion "0.8.1"
|
||||
reportsDir = file("$buildDir/reports")
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jacoco.includeNoLocationClasses = true
|
||||
}
|
||||
|
||||
// run ./gradlew clean createDebugCoverageReport jacocoTestReport
|
||||
task jacocoTestReport(type: JacocoReport) {
|
||||
|
||||
group = "Reporting"
|
||||
description = "Generate Jacoco coverage reports"
|
||||
|
||||
reports {
|
||||
xml.enabled = true
|
||||
html.enabled = true
|
||||
}
|
||||
|
||||
def excludes = [
|
||||
"**/R.class",
|
||||
"**/R\$*.class",
|
||||
"**/*\$ViewInjector*.*",
|
||||
"**/BuildConfig.*",
|
||||
"**/Manifest*.*",
|
||||
"**/*Test*.*",
|
||||
"android/**/*.*",
|
||||
"**/*Fragment.*",
|
||||
"**/*Activity.*"
|
||||
]
|
||||
|
||||
// generated classes
|
||||
classDirectories = fileTree(
|
||||
// Java generated classes on Android project (debug build)
|
||||
dir: "$buildDir/intermediates/classes/debug",
|
||||
excludes: excludes
|
||||
) + fileTree(
|
||||
// Kotlin generated classes on Android project (debug build)
|
||||
dir: "$buildDir/tmp/kotlin-classes/debug",
|
||||
excludes: excludes
|
||||
)
|
||||
|
||||
// sources
|
||||
sourceDirectories = files([
|
||||
android.sourceSets.main.java.srcDirs,
|
||||
"src/main/kotlin"
|
||||
])
|
||||
|
||||
executionData = fileTree(
|
||||
dir: project.projectDir,
|
||||
includes: ["**/*.exec" , "**/*.ec"]
|
||||
)
|
||||
}
|
BIN
app/key-encrypted.p12
Normal file
BIN
app/key-encrypted.p12
Normal file
Binary file not shown.
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.github.wulkanowy.data.db.dao.entities;
|
||||
|
||||
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.entities.School;
|
||||
import io.github.wulkanowy.data.db.dao.entities.SchoolDao;
|
||||
|
||||
public class SchoolTest extends AbstractDaoTestLongPk<SchoolDao, School> {
|
||||
|
||||
public SchoolTest() {
|
||||
super(SchoolDao.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected School createEntity(Long key) {
|
||||
School entity = new School();
|
||||
entity.setId(key);
|
||||
entity.setCurrent(false);
|
||||
return entity;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
3
app/src/debug/res/values-pl/strings.xml
Normal file
3
app/src/debug/res/values-pl/strings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Wulkanowy DEV</string>
|
||||
</resources>
|
3
app/src/debug/res/values/strings.xml
Normal file
3
app/src/debug/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Wulkanowy DEV</string>
|
||||
</resources>
|
@ -10,12 +10,10 @@
|
||||
|
||||
<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"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/WulkanowyTheme">
|
||||
<activity
|
||||
android:name=".ui.splash.SplashActivity"
|
||||
@ -32,19 +30,40 @@
|
||||
android:name=".ui.login.LoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/title_activity_login"
|
||||
android:theme="@style/WulkanowyTheme.DarkActionBar"
|
||||
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"
|
||||
/>
|
||||
<activity
|
||||
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
||||
android:theme="@style/WulkanowyTheme.DarkActionBar" />
|
||||
<activity
|
||||
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
|
||||
android:theme="@style/WulkanowyTheme.DarkActionBar" />
|
||||
|
||||
<service
|
||||
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"
|
||||
|
@ -1,25 +1,25 @@
|
||||
package io.github.wulkanowy;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.core.CrashlyticsCore;
|
||||
import com.jakewharton.threetenabp.AndroidThreeTen;
|
||||
|
||||
import org.greenrobot.greendao.query.QueryBuilder;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.support.DaggerApplication;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||
import eu.davidea.flexibleadapter.utils.Log;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
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.di.DaggerAppComponent;
|
||||
import io.github.wulkanowy.utils.FabricUtils;
|
||||
import io.github.wulkanowy.utils.LoggerUtils;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class WulkanowyApp extends Application {
|
||||
|
||||
protected ApplicationComponent applicationComponent;
|
||||
public class WulkanowyApp extends DaggerApplication {
|
||||
|
||||
@Inject
|
||||
RepositoryContract repository;
|
||||
@ -27,33 +27,48 @@ public class WulkanowyApp extends Application {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
applicationComponent = DaggerApplicationComponent
|
||||
.builder()
|
||||
.applicationModule(new ApplicationModule(this))
|
||||
.build();
|
||||
applicationComponent.inject(this);
|
||||
AndroidThreeTen.init(this);
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
enableDebugLog();
|
||||
}
|
||||
initializeFabric();
|
||||
initializeUserSession();
|
||||
}
|
||||
|
||||
private void initializeUserSession() {
|
||||
if (repository.getSharedRepo().isUserLoggedIn()) {
|
||||
try {
|
||||
repository.getSyncRepo().initLastUser();
|
||||
FabricUtils.logLogin("Open app", true);
|
||||
} catch (Exception e) {
|
||||
FabricUtils.logLogin("Open app", false);
|
||||
Timber.e(e, "An error occurred when the application was started");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void enableDebugLog() {
|
||||
QueryBuilder.LOG_VALUES = true;
|
||||
FlexibleAdapter.enableLogs(Log.Level.DEBUG);
|
||||
FlexibleAdapter.enableLogs(eu.davidea.flexibleadapter.utils.Log.Level.DEBUG);
|
||||
Timber.plant(new LoggerUtils.DebugLogTree());
|
||||
}
|
||||
|
||||
private void initializeFabric() {
|
||||
Fabric.with(new Fabric.Builder(this)
|
||||
.kits(new Crashlytics.Builder()
|
||||
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
|
||||
.build())
|
||||
.kits(
|
||||
new Crashlytics.Builder()
|
||||
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
|
||||
.build(),
|
||||
new Answers()
|
||||
)
|
||||
.debuggable(BuildConfig.DEBUG)
|
||||
.build());
|
||||
Timber.plant(new LoggerUtils.CrashlyticsTree());
|
||||
}
|
||||
|
||||
public ApplicationComponent getApplicationComponent() {
|
||||
return applicationComponent;
|
||||
@Override
|
||||
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
|
||||
return DaggerAppComponent.builder().create(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,143 +1,56 @@
|
||||
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);
|
||||
public SyncContract getSyncRepo() {
|
||||
return synchronization;
|
||||
}
|
||||
|
||||
@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 void cleanAllData() {
|
||||
sharedPref.cleanSharedPref();
|
||||
database.recreateDatabase();
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,22 @@
|
||||
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;
|
||||
SyncContract getSyncRepo();
|
||||
|
||||
Account getCurrentUser();
|
||||
|
||||
Week getWeek(String date);
|
||||
|
||||
List<Grade> getNewGrades();
|
||||
void cleanAllData();
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
package io.github.wulkanowy.data.db.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.entities.Grade;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Symbol;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Week;
|
||||
|
||||
public interface DbContract {
|
||||
|
||||
Week getWeek(String date);
|
||||
|
||||
Week getWeek(long diaryId, String date);
|
||||
|
||||
List<Subject> getSubjectList(int semesterName);
|
||||
|
||||
List<Grade> getNewGrades(int semesterName);
|
||||
|
||||
long getCurrentSchoolId();
|
||||
|
||||
long getCurrentStudentId();
|
||||
|
||||
long getCurrentSymbolId();
|
||||
|
||||
Symbol getCurrentSymbol();
|
||||
|
||||
long getCurrentDiaryId();
|
||||
|
||||
long getSemesterId(int name);
|
||||
|
||||
long getCurrentSemesterId();
|
||||
|
||||
int getCurrentSemesterName();
|
||||
|
||||
void recreateDatabase();
|
||||
}
|
@ -1,19 +1,102 @@
|
||||
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.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import io.github.wulkanowy.api.Vulcan;
|
||||
import io.github.wulkanowy.data.db.dao.entities.DaoMaster;
|
||||
import io.github.wulkanowy.di.annotations.ApplicationContext;
|
||||
import io.github.wulkanowy.di.annotations.DatabaseInfo;
|
||||
import io.github.wulkanowy.data.db.dao.migrations.Migration23;
|
||||
import io.github.wulkanowy.data.db.dao.migrations.Migration26;
|
||||
import io.github.wulkanowy.data.db.dao.migrations.Migration27;
|
||||
import io.github.wulkanowy.data.db.dao.migrations.Migration28;
|
||||
import io.github.wulkanowy.data.db.dao.migrations.Migration29;
|
||||
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
|
||||
import timber.log.Timber;
|
||||
|
||||
@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(Context context, @Named("dbName") 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) {
|
||||
Timber.i("Cleaning user data oldVersion=%s newVersion=%s", oldVersion, 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 {
|
||||
Timber.i("Applying migration to db schema v%s...", migration.getVersion());
|
||||
migration.runMigration(db, sharedPref, vulcan);
|
||||
Timber.i("Migration %s complete", migration.getVersion());
|
||||
} catch (Exception e) {
|
||||
Timber.e(e, "Failed to apply migration");
|
||||
recreateDatabase(db);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recreateDatabase(Database db) {
|
||||
Timber.i("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());
|
||||
migrations.add(new Migration27());
|
||||
migrations.add(new Migration28());
|
||||
migrations.add(new Migration29());
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,132 @@
|
||||
package io.github.wulkanowy.data.db.dao;
|
||||
|
||||
import org.greenrobot.greendao.database.Database;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.entities.DaoMaster;
|
||||
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
|
||||
import io.github.wulkanowy.data.db.dao.entities.DiaryDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Grade;
|
||||
import io.github.wulkanowy.data.db.dao.entities.GradeDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.SchoolDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Semester;
|
||||
import io.github.wulkanowy.data.db.dao.entities.SemesterDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.StudentDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Symbol;
|
||||
import io.github.wulkanowy.data.db.dao.entities.SymbolDao;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Week;
|
||||
import io.github.wulkanowy.data.db.dao.entities.WeekDao;
|
||||
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
|
||||
|
||||
public class DbRepository implements DbContract {
|
||||
|
||||
private final DaoSession daoSession;
|
||||
|
||||
private final SharedPrefContract sharedPref;
|
||||
|
||||
@Inject
|
||||
DbRepository(DaoSession daoSession, SharedPrefContract sharedPrefContract) {
|
||||
this.daoSession = daoSession;
|
||||
this.sharedPref = sharedPrefContract;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Week getWeek(String date) {
|
||||
return getWeek(getCurrentDiaryId(), date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Week getWeek(long diaryId, String date) {
|
||||
return daoSession.getWeekDao().queryBuilder().where(
|
||||
WeekDao.Properties.StartDayDate.eq(date),
|
||||
WeekDao.Properties.DiaryId.eq(diaryId)
|
||||
).unique();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subject> getSubjectList(int semesterName) {
|
||||
return daoSession.getSemesterDao().load(getSemesterId(semesterName)).getSubjectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Grade> getNewGrades(int semesterName) {
|
||||
return daoSession.getGradeDao().queryBuilder().where(
|
||||
GradeDao.Properties.IsNew.eq(1),
|
||||
GradeDao.Properties.SemesterId.eq(getSemesterId(semesterName))
|
||||
).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Symbol getCurrentSymbol() {
|
||||
return daoSession.getSymbolDao().queryBuilder().where(
|
||||
SymbolDao.Properties.UserId.eq(sharedPref.getCurrentUserId())
|
||||
).unique();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentSymbolId() {
|
||||
return getCurrentSymbol().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentSchoolId() {
|
||||
return daoSession.getSchoolDao().queryBuilder().where(
|
||||
SchoolDao.Properties.SymbolId.eq(getCurrentSymbolId()),
|
||||
SchoolDao.Properties.Current.eq(true)
|
||||
).unique().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentStudentId() {
|
||||
return daoSession.getStudentDao().queryBuilder().where(
|
||||
StudentDao.Properties.SchoolId.eq(getCurrentSchoolId()),
|
||||
StudentDao.Properties.Current.eq(true)
|
||||
).unique().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentDiaryId() {
|
||||
return daoSession.getDiaryDao().queryBuilder().where(
|
||||
DiaryDao.Properties.StudentId.eq(getCurrentStudentId()),
|
||||
DiaryDao.Properties.Current.eq(true)
|
||||
).unique().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSemesterId(int name) {
|
||||
return daoSession.getSemesterDao().queryBuilder().where(
|
||||
SemesterDao.Properties.DiaryId.eq(getCurrentDiaryId()),
|
||||
SemesterDao.Properties.Name.eq(String.valueOf(name))
|
||||
).unique().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentSemesterId() {
|
||||
return getCurrentSemester().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentSemesterName() {
|
||||
return Integer.valueOf(getCurrentSemester().getName());
|
||||
}
|
||||
|
||||
private Semester getCurrentSemester() {
|
||||
return daoSession.getSemesterDao().queryBuilder().where(
|
||||
SemesterDao.Properties.DiaryId.eq(getCurrentDiaryId()),
|
||||
SemesterDao.Properties.Current.eq(true)
|
||||
).unique();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recreateDatabase() {
|
||||
Database database = daoSession.getDatabase();
|
||||
|
||||
DaoMaster.dropAllTables(database, true);
|
||||
DaoMaster.createAllTables(database, true);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user