Compare commits
666 commits
support/1.
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
340245d8cc | ||
|
018623b809 | ||
|
9b7e8585b0 | ||
|
77d6083752 | ||
|
aab4d4f971 | ||
|
b2c289349f | ||
|
e015980284 | ||
|
fe53c38f75 | ||
|
444dbc67f2 | ||
|
f7c24e7725 | ||
|
1a1878acd9 | ||
|
7f9456fe6c | ||
|
be44f3b25c | ||
|
3463188b41 | ||
|
414209d8da | ||
|
4d263fa4d7 | ||
|
edd743d1e4 | ||
|
fc343c3cbf | ||
|
c812f272eb | ||
|
1f6a0471e5 | ||
|
c8fb4478ce | ||
|
3f7e8eba8e | ||
|
f42bdaaf48 | ||
|
2ebd08cf44 | ||
|
d3594f3861 | ||
|
ccd2a96f3d | ||
|
28edf8a006 | ||
|
d838b0d338 | ||
|
3235599ff7 | ||
|
09f9a39550 | ||
|
b8ff96f5fd | ||
|
bc52de44f9 | ||
|
00de384ca2 | ||
|
905a74524b | ||
|
e4b2a70831 | ||
|
0c3d9bd382 | ||
|
5558b73771 | ||
|
5127c75edf | ||
|
0a779b148b | ||
|
b5238db5d4 | ||
|
1eeea1e249 | ||
|
0989dc2442 | ||
|
20813d9978 | ||
|
0e49ff8549 | ||
|
f644b2a2a2 | ||
|
2cadf274f1 | ||
|
660e075cce | ||
|
de2a887188 | ||
|
29a1dc73f7 | ||
|
b0f9653c0b | ||
|
d28f3e6f1c | ||
|
209ea24aa7 | ||
|
03066e18a2 | ||
|
50e06b2a06 | ||
|
fdaae2b913 | ||
|
c653ca7148 | ||
|
6fff07e52a | ||
|
ce84113020 | ||
|
5999e046e4 | ||
|
c1e40d8538 | ||
|
f50690a95a | ||
|
2f4bbfdc70 | ||
|
48a6c72d00 | ||
|
816e41f41f | ||
|
e970108661 | ||
|
1be3e9fa42 | ||
|
35d0a5a327 | ||
|
8ddca83b53 | ||
|
460b09ad7e | ||
|
6416b16b88 | ||
|
0766e5b30a | ||
|
4f90df84a0 | ||
|
06119e4a55 | ||
|
b57cbe04e8 | ||
|
0cca5034c6 | ||
|
d440e46498 | ||
|
41e77aaa09 | ||
|
7c081268b4 | ||
|
ebb54d067b | ||
|
91736bf8a0 | ||
|
8abb8a9490 | ||
|
fa8ef5ab9f | ||
|
44bc5e1723 | ||
|
979649a57d | ||
|
676e837401 | ||
|
d251656df6 | ||
|
f1084de2cd | ||
|
66680fbaa7 | ||
|
905da09e1e | ||
|
39668c543f | ||
|
8dc36dd101 | ||
|
609381bfee | ||
|
d1f65c851e | ||
|
11873c7ee7 | ||
|
3331b6b65f | ||
|
d32f1b75ed | ||
|
5239094360 | ||
|
d766d243be | ||
|
617b4eb62c | ||
|
2c498c5d85 | ||
|
a579beb91d | ||
|
a5181dcfbb | ||
|
1d9e0109b6 | ||
|
15c0e15ef8 | ||
|
af6a8c66e7 | ||
|
bef50f7f68 | ||
|
0f1974643a | ||
|
dde984685b | ||
|
8902a0c463 | ||
|
71654e3186 | ||
|
5459ac7fc4 | ||
|
35dec57cb6 | ||
|
a324bee117 | ||
|
9d11cce2ea | ||
|
3d5bfea0bd | ||
|
5dfe351104 | ||
|
a3adb07eb1 | ||
|
969cf79d97 | ||
|
44c31fa0d5 | ||
|
b4941cb70a | ||
|
8b444cad99 | ||
|
d9f750deea | ||
|
10cda38505 | ||
|
c1c8cbe4c0 | ||
|
43d4cf2eb3 | ||
|
e27a5f19bb | ||
|
545a90e2a0 | ||
|
dab976890f | ||
|
cd31377aed | ||
|
28fc7a7d40 | ||
|
67c637b91b | ||
|
e0a5753e11 | ||
|
8e26580752 | ||
|
6261efbc3d | ||
|
ebd4a8b90b | ||
|
3ee9a2e132 | ||
|
c2f8981ad4 | ||
|
c847d37c9f | ||
|
1ae931c5a0 | ||
|
da19305b31 | ||
|
b2cc35e317 | ||
|
1b6e840917 | ||
|
2583e044e7 | ||
|
801089a7b1 | ||
|
e73761051a | ||
|
72ec14c148 | ||
|
3e4d549d79 | ||
|
91e847ee47 | ||
|
e86fd1b332 | ||
|
6bcdadad88 | ||
|
dda1dc908b | ||
|
45cbe64fd0 | ||
|
f04da5385b | ||
|
d4f6f3571c | ||
|
a618b19dd3 | ||
|
990eecc5d5 | ||
|
f53776c373 | ||
|
5cbe97b9a0 | ||
|
8428eb6ce9 | ||
|
a3da581298 | ||
|
3c7d8b9545 | ||
|
fd5eb26a9d | ||
|
0d225dc30f | ||
|
d26a5513ac | ||
|
5bfcd16c0b | ||
|
4071569fb4 | ||
|
1c67564742 | ||
|
94083e087f | ||
|
8f3a35c153 | ||
|
cc9615f5b1 | ||
|
d17eaa2190 | ||
|
db89678f5b | ||
|
f53fc32821 | ||
|
eaff0f4bf2 | ||
|
eb2a967ef6 | ||
|
aba27876c2 | ||
|
4a9dadc042 | ||
|
41aef1a68b | ||
|
79f55fba1d | ||
|
e97d565bbf | ||
|
03fb607415 | ||
|
badcf2460d | ||
|
bcb7797733 | ||
|
83e59cca40 | ||
|
939e4428c8 | ||
|
acabb144bd | ||
|
04661c77f0 | ||
|
c0b5cd2b63 | ||
|
8ffd7b0d35 | ||
|
e077867957 | ||
|
b7081d1ac1 | ||
|
fcdf0aaf1e | ||
|
73ad35c0e6 | ||
|
10040718e9 | ||
|
8143878d88 | ||
|
8dfcb1b881 | ||
|
49b282cd34 | ||
|
73260402c6 | ||
|
fbc50399e0 | ||
|
b5f64f0dbc | ||
|
743cc22760 | ||
|
0171e7b246 | ||
|
fa883c411e | ||
|
78fda15f02 | ||
|
8632c2f425 | ||
|
fc4b8260ea | ||
|
4e64026b8f | ||
|
c8037914ca | ||
|
33b64c6427 | ||
|
29bf265a71 | ||
|
5e066fe9a9 | ||
|
81028998e1 | ||
|
ce3296fc43 | ||
|
150c0957ca | ||
|
1056a1ff2a | ||
|
c900846ca9 | ||
|
48af6bfc14 | ||
|
06a2e33822 | ||
|
7017d55c81 | ||
|
0156b4ba51 | ||
|
cd68beb772 | ||
|
0bba02045f | ||
|
640fb0913b | ||
|
60a6d31b45 | ||
|
b039d531c3 | ||
|
f23585e489 | ||
|
c2edf9498b | ||
|
d4d878065e | ||
|
a7f5fa26af | ||
|
212f0e33d5 | ||
|
6c7c919978 | ||
|
fd3d4ac624 | ||
|
06ba354ef4 | ||
|
c895c42059 | ||
|
55afa6836d | ||
|
e23e5bc2d2 | ||
|
8271de8dfb | ||
|
8926db8525 | ||
|
04d34c018f | ||
|
6e3c3418b4 | ||
|
e3951be709 | ||
|
8c8af98a36 | ||
|
4a7a502c1a | ||
|
e29d72ae09 | ||
|
7f6585b69c | ||
|
444caeafa7 | ||
|
ee396f1650 | ||
|
f378f912d0 | ||
|
7caaddcf51 | ||
|
96464549f0 | ||
|
62fcec2bb4 | ||
|
dbe881c05b | ||
|
b6566da99f | ||
|
526df3c8aa | ||
|
2e615da85f | ||
|
c0dc1bdfbb | ||
|
40d7e85d75 | ||
|
ce4695a7a1 | ||
|
4a2f8e88e7 | ||
|
5000080a7a | ||
|
049c428fd3 | ||
|
d9da6614e7 | ||
|
59384cafa1 | ||
|
9409a90dde | ||
|
bfd4439132 | ||
|
62d7b56a9d | ||
|
a8f4c11db1 | ||
|
65011203ec | ||
|
0d596d770b | ||
|
7c7bef0722 | ||
|
9442a1db44 | ||
|
d77189664c | ||
|
fc3ecf7257 | ||
|
bd81855a28 | ||
|
a29fb83318 | ||
|
f16c029c16 | ||
|
5f2128721c | ||
|
e3706b0398 | ||
|
11d2063201 | ||
|
46a4c3b139 | ||
|
88fbdfc8d9 | ||
|
fc3b386a2e | ||
|
d0f87da8d1 | ||
|
f0c7093521 | ||
|
29af590dd8 | ||
|
65fdac0cf6 | ||
|
3b2616561c | ||
|
9a26dab997 | ||
|
a56a163cbe | ||
|
f6195151e3 | ||
|
fa42a71287 | ||
|
e7540e7599 | ||
|
8695e7bac5 | ||
|
42cab75447 | ||
|
d062bd1a74 | ||
|
717943fd32 | ||
|
eb7d179c68 | ||
|
7af0f5c0a6 | ||
|
186dfcb767 | ||
|
622c11a86b | ||
|
48f82f28b5 | ||
|
57cf508cdf | ||
|
c7f9b4bbe0 | ||
|
4eb33ca209 | ||
|
358e12113c | ||
|
61f9d6abe0 | ||
|
faca5a161b | ||
|
6c1fe18065 | ||
|
f3646bf851 | ||
|
0e47d7afdf | ||
|
bca5158a1c | ||
|
96051b36bc | ||
|
368cfac7b1 | ||
|
33f05d67ed | ||
|
16cb07f73e | ||
|
d1486bade5 | ||
|
567679d1a0 | ||
|
773402ceb1 | ||
|
f9be659490 | ||
|
69651688f0 | ||
|
d196b49046 | ||
|
4a67e1e3fa | ||
|
d6bdb4e74a | ||
|
95eafd838f | ||
|
20ea9fa4cc | ||
|
6b2c69833f | ||
|
6087e79308 | ||
|
ecc58a4d8a | ||
|
05f8073499 | ||
|
e639d0e751 | ||
|
f66c7e9998 | ||
|
e37a007e48 | ||
|
41b8496045 | ||
|
05be2d1d9d | ||
|
43c85e6695 | ||
|
6f06410133 | ||
|
c17fcee052 | ||
|
b72bc42cbc | ||
|
d83be8fb12 | ||
|
3d9aa4c6ff | ||
|
94261a487a | ||
|
fc5719d166 | ||
|
742b218c61 | ||
|
8387bef56c | ||
|
485e4bef99 | ||
|
97c46aa410 | ||
|
f96563dc21 | ||
|
9e76c0cf4e | ||
|
a92198fc8f | ||
|
38e6bcfa8a | ||
|
b86f188dba | ||
|
c1573f04c5 | ||
|
f7716915d3 | ||
|
d897ce49ae | ||
|
5ce34018e3 | ||
|
fa4b1aa7e0 | ||
|
60f8a506a5 | ||
|
14267a9a89 | ||
|
8973b01694 | ||
|
62d5ff05ef | ||
|
8726501d8b | ||
|
81951eb29f | ||
|
f42afd1602 | ||
|
432241919a | ||
|
b5028a6437 | ||
|
fb76454793 | ||
|
99bc1db9f5 | ||
|
7a0c173925 | ||
|
b040618458 | ||
|
0a1268e5af | ||
|
33ccfdb77b | ||
|
3e3f17151a | ||
|
2e8eb1de3c | ||
|
efd332d4f3 | ||
|
a18fe84ce7 | ||
|
24b5b16f72 | ||
|
4ef106e4c9 | ||
|
51dd70067b | ||
|
6b602b35d6 | ||
|
0fb794e246 | ||
|
c55d0bf251 | ||
|
8dfcd24753 | ||
|
17e702834b | ||
|
22018ce911 | ||
|
e2ddf47f29 | ||
|
57660cc7c9 | ||
|
d228df6c6d | ||
|
d3b74448f8 | ||
|
522241b5de | ||
|
d85a85235f | ||
|
64b007425f | ||
|
32d6505e4b | ||
|
430e388b7d | ||
|
8f01c8c98a | ||
|
8c1af1192d | ||
|
07d68f5425 | ||
|
4ce5701f5a | ||
|
c057907efa | ||
|
a71c27a3b4 | ||
|
8d37efb8e8 | ||
|
ae322f4966 | ||
|
76e6a0e5bd | ||
|
d9638eeba7 | ||
|
8adeb5842f | ||
|
06304ded47 | ||
|
1a68b5af21 | ||
|
995e652716 | ||
|
5cb09ec919 | ||
|
2aea471b94 | ||
|
492f8ede8f | ||
|
615a9b8cc4 | ||
|
2bab8112cf | ||
|
ba495da583 | ||
|
cd3b738e81 | ||
|
5e02645dd3 | ||
|
f87dd17bae | ||
|
34814cc062 | ||
|
d8baaedb09 | ||
|
3bcc87b4a0 | ||
|
b883539c1f | ||
|
b02a093c4b | ||
|
5143ad223f | ||
|
3a8b351d2b | ||
|
8def0961c6 | ||
|
6a3e04f0af | ||
|
366a52afee | ||
|
b95bd8004c | ||
|
8189776975 | ||
|
510f067bb0 | ||
|
af6595de1f | ||
|
d19d74d254 | ||
|
6b8049af23 | ||
|
3012cdd678 | ||
|
2d0fc79855 | ||
|
a3b97edd48 | ||
|
3c5a4d66ce | ||
|
c9005720c9 | ||
|
a0572e7743 | ||
|
a2ff889ee4 | ||
|
170485fea2 | ||
|
0ab26a65dd | ||
|
f4b4c70b67 | ||
|
19260cd862 | ||
|
285a03b5c2 | ||
|
a5389a960c | ||
|
73fe1e21fc | ||
|
34a0059df9 | ||
|
bf63509acd | ||
|
0b487191ec | ||
|
3b25f5d9bf | ||
|
42dbd67a39 | ||
|
55b2283c33 | ||
|
c42d008bbf | ||
|
41e7140216 | ||
|
98b37273bb | ||
|
c74512daa7 | ||
|
d66c9805b2 | ||
|
bc992b3f85 | ||
|
8e99f6baf6 | ||
|
336187c93e | ||
|
1ac8a7bf33 | ||
|
44965445df | ||
|
41168eec22 | ||
|
e2e1081405 | ||
|
876b00ca32 | ||
|
12250eb07f | ||
|
701016eda2 | ||
|
868009a3e6 | ||
|
07a05b0db1 | ||
|
497f4f5910 | ||
|
7745db956c | ||
|
588d8b3022 | ||
|
0169e7ace5 | ||
|
4bfd823e39 | ||
|
f65faabbd7 | ||
|
ba6e403d21 | ||
|
2840d9d6d0 | ||
|
f3acb5df18 | ||
|
bc21110445 | ||
|
0d43710ac6 | ||
|
f1340f1696 | ||
|
459faf2932 | ||
|
dcd8bd8b19 | ||
|
c8e3e4f9fd | ||
|
2749540049 | ||
|
4d591f2672 | ||
|
43f462c49d | ||
|
0e00d4d2ac | ||
|
006a238bda | ||
|
e92e696725 | ||
|
21e4d75e1b | ||
|
047c1f83c8 | ||
|
2a7743f56f | ||
|
ca19c41b04 | ||
|
a1bf69486b | ||
|
09e5215894 | ||
|
a19f3c8648 | ||
|
8485454de4 | ||
|
12ffe47326 | ||
|
cad9b16a5f | ||
|
4ca1b6bcea | ||
|
925ff6e157 | ||
|
e26ab8ccf6 | ||
|
dbe87aac67 | ||
|
b78b1c1efb | ||
|
40ad359073 | ||
|
d90ba40e55 | ||
|
af0ec25114 | ||
|
bc76d18427 | ||
|
c38f2734fc | ||
|
985d751fc3 | ||
|
8b21629478 | ||
|
90687bdc3d | ||
|
09965f5965 | ||
|
2a14fd19b7 | ||
|
19dd28401d | ||
|
041953380d | ||
|
007176fed2 | ||
|
cadf48de4a | ||
|
b210dcac04 | ||
|
9176c250ca | ||
|
32d1dce278 | ||
|
44a8180292 | ||
|
b41a4e2f22 | ||
|
c3db2cdc3d | ||
|
cf29b966d6 | ||
|
ceafa0f411 | ||
|
1825a9a60d | ||
|
2e46ab689f | ||
|
497713dac9 | ||
|
3f77767434 | ||
|
26230e50e7 | ||
|
59042d9458 | ||
|
4c50ae000f | ||
|
9032e33686 | ||
|
e18302b50f | ||
|
2f1c0a20af | ||
|
84b6675269 | ||
|
bafb07cf5d | ||
|
aec4ea5221 | ||
|
953233590b | ||
|
0a1171b8f9 | ||
|
5ae2a915fd | ||
|
b0d057ca21 | ||
|
16811fbe90 | ||
|
44184f07f7 | ||
|
42d4731dd7 | ||
|
fdedb95207 | ||
|
a8ba963a0b | ||
|
189f5ecee0 | ||
|
3ecb494372 | ||
|
19be4c01f9 | ||
|
f0d07bb30c | ||
|
abc43f7fd3 | ||
|
fba873461e | ||
|
14ae84db0b | ||
|
f0272ef252 | ||
|
e70e970d32 | ||
|
fd6125f322 | ||
|
3b17f04b9d | ||
|
442bd060d7 | ||
|
aea2fb4b88 | ||
|
9d9a18c5c2 | ||
|
c2a82ae136 | ||
|
2447e0de15 | ||
|
65f1a02936 | ||
|
dd87697f59 | ||
|
6394571614 | ||
|
57680ecb3f | ||
|
4e5cb29ce5 | ||
|
db5820b81b | ||
|
5713a6d1ee | ||
|
6e1b8eb26a | ||
|
f6f32b755a | ||
|
fbb42782b3 | ||
|
d653df338a | ||
|
27f95f923c | ||
|
4e88b0f8d4 | ||
|
7b52d0e5e1 | ||
|
8971d39691 | ||
|
42bce37748 | ||
|
7efab423b5 | ||
|
aa7b141cb5 | ||
|
01c62bffbe | ||
|
4e9fa5d240 | ||
|
e472eec5a2 | ||
|
dd0d3f03e6 | ||
|
c5a6fa275c | ||
|
5b9cd070d4 | ||
|
a45110c8de | ||
|
15477ccdfa | ||
|
1738c40121 | ||
|
fffa4d7d91 | ||
|
4f85472244 | ||
|
4efd64264b | ||
|
a0a30a7944 | ||
|
12548d8746 | ||
|
07316b4ffd | ||
|
64826b4119 | ||
|
3470eaffa9 | ||
|
4b24f2946c | ||
|
cdc6049d29 | ||
|
f94cdfea16 | ||
|
96ee8ba947 | ||
|
364f3c0295 | ||
|
f62736adb0 | ||
|
5151856da1 | ||
|
9ccb4298d8 | ||
|
49c2071d10 | ||
|
230d2075df | ||
|
5a8f9c6206 | ||
|
e7f36785d7 | ||
|
783733eaf7 | ||
|
c3b021e8f7 | ||
|
8f3721f1f9 | ||
|
b9a45cfb4b | ||
|
90d6a13275 | ||
|
d74acd3989 | ||
|
792ac61884 | ||
|
66cfe3e996 | ||
|
55980b2178 | ||
|
7b28b74502 | ||
|
3cbb26b6f9 | ||
|
7c399ffaea | ||
|
46ce30f2b8 | ||
|
d01e5f5299 | ||
|
5c17530cd9 | ||
|
b991d0c5b6 | ||
|
f15cc8223a | ||
|
18e16b2034 | ||
|
ae8798806d | ||
|
496dc01d15 | ||
|
88111ea725 | ||
|
bb083546e0 | ||
|
e282a7a50e | ||
|
b70f3be069 | ||
|
f66cac410a | ||
|
15eb227965 | ||
|
f3f37e9066 | ||
|
d0c4470ccb | ||
|
d212ea8109 | ||
|
f7e0df0241 | ||
|
eab3580749 | ||
|
f8b0b6bfac | ||
|
3fa6936c2f | ||
|
a2c270c9d2 | ||
|
567705a2d4 | ||
|
8580cac720 | ||
|
50f74b2c6a | ||
|
2005f3f60d | ||
|
5d07788345 | ||
|
8bf1de5d05 | ||
|
9606d8bf79 | ||
|
5afc998441 | ||
|
b5920ae7c1 | ||
|
fe87a7c21e | ||
|
f7e2d3c88c | ||
|
d85e16cdcd | ||
|
07a21c110e | ||
|
6ed5b675a1 | ||
|
2334d340e5 | ||
|
877b913588 | ||
|
e21c18cb70 | ||
|
9bd61f8fe9 | ||
|
9f172c1056 | ||
|
f14abea44c |
491 changed files with 20408 additions and 9146 deletions
|
@ -1,70 +0,0 @@
|
|||
version: 2.1
|
||||
|
||||
references:
|
||||
workspace_root: &workspace_root
|
||||
~/sdk
|
||||
|
||||
container_config: &container_config
|
||||
docker:
|
||||
- image: circleci/openjdk:8-jdk-stretch
|
||||
working_directory: *workspace_root
|
||||
|
||||
attach_workspace: &attach_workspace
|
||||
attach_workspace:
|
||||
at: *workspace_root
|
||||
|
||||
general_cache_key: &general_cache_key
|
||||
key: cache-{{ checksum "build.gradle" }}
|
||||
paths:
|
||||
- ~/.gradle
|
||||
|
||||
jobs:
|
||||
test:
|
||||
<<: *container_config
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- checkout
|
||||
- restore_cache:
|
||||
<<: *general_cache_key
|
||||
|
||||
- run: ./.circleci/host-hotfix.sh
|
||||
- run: ./gradlew build -x check --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||
- run: ./gradlew check jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||
|
||||
- save_cache:
|
||||
<<: *general_cache_key
|
||||
|
||||
- run: bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
- store_test_results:
|
||||
path: ./build/test-results
|
||||
- store_artifacts:
|
||||
path: ./build/reports/jacoco/test
|
||||
- store_test_results:
|
||||
path: ./build/reports/tests/test
|
||||
- store_artifacts:
|
||||
path: ./build/libs/sdk-1.1.5.jar
|
||||
deploy:
|
||||
<<: *container_config
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- checkout
|
||||
- restore_cache:
|
||||
<<: *general_cache_key
|
||||
|
||||
- run: ./gradlew bintrayUpload --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
test-and-deploy:
|
||||
jobs:
|
||||
- test
|
||||
- deploy:
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
tags:
|
||||
only: /\d+\.\d+\.\d+/
|
||||
branches:
|
||||
ignore: /.*/
|
|
@ -1,9 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "127.0.0.1 fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 adfs.fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 adfslight.fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 cufs.fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 uonetplus.fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 uonetplus-uzytkownik.fakelog.localhost" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 uonetplus-uczen.fakelog.localhost" | sudo tee -a /etc/hosts
|
|
@ -5,9 +5,23 @@ insert_final_newline=true
|
|||
indent_style=space
|
||||
indent_size=4
|
||||
|
||||
[*.json]
|
||||
[*.{json,xml}]
|
||||
indent_size=2
|
||||
|
||||
[*.{kt,kts}]
|
||||
disabled_rules=import-ordering,no-wildcard-imports
|
||||
max_line_length=177
|
||||
ij_kotlin_allow_trailing_comma_on_call_site=true
|
||||
ij_kotlin_allow_trailing_comma=true
|
||||
|
||||
ktlint_standard_no-empty-first-line-in-class-body=disabled
|
||||
ktlint_standard_function-signature=disabled
|
||||
ktlint_standard_string-template-indent=disabled
|
||||
ktlint_standard_string-template-indent-expression-wrapping=disabled
|
||||
ktlint_standard_multiline-expression-wrapping=disabled
|
||||
ktlint_standard_max-line-length=disabled
|
||||
ktlint_standard_no-blank-line-in-list=disabled
|
||||
ktlint_standard_parameter-list-wrapping=disabled
|
||||
ktlint_standard_discouraged-comment-location=disabled
|
||||
ktlint_standard_if-else-wrapping=disabled
|
||||
ktlint_standard_property-naming=disabled
|
||||
ktlint_standard_class-naming=disabled
|
||||
|
|
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gradle
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: org.jetbrains.kotlinx:kotlinx-coroutines-core
|
||||
versions:
|
||||
- 1.4.3-native-mt
|
||||
- dependency-name: org.jetbrains.kotlinx:kotlinx-coroutines-test
|
||||
versions:
|
||||
- 1.4.3-native-mt
|
||||
- dependency-name: org.jlleitschuh.gradle.ktlint
|
||||
versions:
|
||||
- 9.4.1
|
31
.github/workflows/deploy.yml
vendored
Normal file
31
.github/workflows/deploy.yml
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
deploy-sonatype:
|
||||
name: Deploy to sonatype
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: ossrh
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||
- name: Build and publish
|
||||
env:
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||
MAVEN_SIGNING_KEY: ${{ secrets.MAVEN_SIGNING_KEY }}
|
||||
MAVEN_SIGNING_PASSWORD: ${{ secrets.MAVEN_SIGNING_PASSWORD }}
|
||||
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository --stacktrace
|
48
.github/workflows/docs.yml
vendored
Normal file
48
.github/workflows/docs.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: fkirc/skip-duplicate-actions@master
|
||||
- uses: actions/checkout@v3
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 11
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||
- name: Generate docs
|
||||
run: ./gradlew mkdocsBuild
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
path: ./build/mkdocs
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
pages: write
|
||||
needs: docs
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
59
.github/workflows/test.yml
vendored
Normal file
59
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
name: Unit tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: fkirc/skip-duplicate-actions@master
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||
- name: Unit tests
|
||||
run: |
|
||||
./gradlew test --stacktrace
|
||||
./gradlew jacocoTestReport --stacktrace
|
||||
- name: API changes check
|
||||
run: |
|
||||
./gradlew :sdk:apiCheck --stacktrace
|
||||
./gradlew :sdk-hebe:apiCheck --stacktrace
|
||||
./gradlew :sdk-scrapper:apiCheck --stacktrace
|
||||
# - uses: codecov/codecov-action@v1
|
||||
|
||||
lint:
|
||||
name: Lint check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: fkirc/skip-duplicate-actions@master
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||
- name: Lint
|
||||
run: |
|
||||
./gradlew ktlintCheck --stacktrace
|
||||
# - uses: codecov/codecov-action@v1
|
38
.gitignore
vendored
38
.gitignore
vendored
|
@ -22,8 +22,36 @@
|
|||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
.idea/
|
||||
!.idea/codeStyles/
|
||||
# IntelliJ configurations
|
||||
*.iml
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
#.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
.idea/navEditor.xml
|
||||
.idea/caches/
|
||||
.idea/libraries/
|
||||
.idea/shelf/
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/encodings.xml
|
||||
.idea/misc.xml
|
||||
.idea/scopes/scope_settings.xml
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
.idea/datasources.xml
|
||||
.idea/dataSources.ids
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
.idea/runConfigurations.xml
|
||||
.idea/discord.xml
|
||||
.idea/jarRepositories.xml
|
||||
.gradle
|
||||
build/
|
||||
out/
|
||||
|
@ -43,3 +71,9 @@ gradle-app.setting
|
|||
*iml
|
||||
classes
|
||||
.DS_Store
|
||||
.idea/libraries-with-intellij-classes.xml
|
||||
.idea/kotlinc.xml
|
||||
.idea/jpa-buddy.xml
|
||||
.idea/kotlinScripting.xml
|
||||
Snap.*.trc
|
||||
javacore.*.txt
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="RIGHT_MARGIN" value="155" />
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
|
||||
|
@ -24,13 +25,6 @@
|
|||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="5" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<option name="WRAP_ON_TYPING" value="0" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
|
|
20
.idea/gradle.xml
Normal file
20
.idea/gradle.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="corretto-17" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/sdk" />
|
||||
<option value="$PROJECT_DIR$/sdk-hebe" />
|
||||
<option value="$PROJECT_DIR$/sdk-scrapper" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
25
.idea/jsonSchemas.xml
Normal file
25
.idea/jsonSchemas.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||
<state>
|
||||
<map>
|
||||
<entry key="GitHub Workflow">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="GitHub Workflow" />
|
||||
<option name="relativePathToSchema" value="https://json.schemastore.org/github-workflow.json" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="path" value=".github/workflows/deploy.yml" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</state>
|
||||
</component>
|
||||
</project>
|
2
LICENSE
2
LICENSE
|
@ -186,7 +186,7 @@
|
|||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Wulkanowy
|
||||
Copyright 2023 Wulkanowy
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
16
README.md
16
README.md
|
@ -1,8 +1,9 @@
|
|||
# VULCAN UONET+ SDK
|
||||
|
||||
[![GitHub Workflow status](https://img.shields.io/github/actions/workflow/status/wulkanowy/sdk/test.yml?branch=master&style=flat-square)](https://github.com/wulkanowy/sdk/actions)
|
||||
[![Codecov branch](https://img.shields.io/codecov/c/github/wulkanowy/sdk/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/sdk)
|
||||
[![CircleCI branch](https://img.shields.io/circleci/project/github/wulkanowy/sdk/master.svg?style=flat-square)](https://circleci.com/gh/wulkanowy/sdk)
|
||||
[![Bintray](https://img.shields.io/bintray/v/wulkanowy/wulkanowy/sdk.svg?style=flat-square)](https://bintray.com/wulkanowy/wulkanowy/sdk)
|
||||
[![Maven Central](https://img.shields.io/maven-central/v/io.github.wulkanowy/sdk?style=flat-square)](https://search.maven.org/artifact/io.github.wulkanowy/sdk)
|
||||
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.wulkanowy/sdk?server=https%3A%2F%2Fs01.oss.sonatype.org&style=flat-square)](https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/wulkanowy/sdk/)
|
||||
[![JitPack](https://img.shields.io/jitpack/v/wulkanowy/sdk.svg?style=flat-square)](https://jitpack.io/#wulkanowy/sdk)
|
||||
[![License](https://img.shields.io/github/license/wulkanowy/sdk.svg?style=flat-square)](https://github.com/wulkanowy/sdk)
|
||||
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
|
||||
|
@ -14,7 +15,6 @@
|
|||
Check it out [full public api](https://github.com/wulkanowy/sdk/blob/master/sdk/src/main/kotlin/io/github/wulkanowy/sdk/Sdk.kt)
|
||||
and [test examples](https://github.com/wulkanowy/sdk/blob/master/sdk/src/test/kotlin/io/github/wulkanowy/sdk/SdkRemoteTest.kt).
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
Check [wiki page](https://github.com/wulkanowy/sdk/wiki).
|
||||
|
@ -24,11 +24,17 @@ Check [wiki page](https://github.com/wulkanowy/sdk/wiki).
|
|||
```gradle
|
||||
allprojects {
|
||||
repositories {
|
||||
...
|
||||
// for stable releases
|
||||
mavenCentral()
|
||||
|
||||
// for snapshots
|
||||
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/" }
|
||||
|
||||
// for everything
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'io.github.wulkanowy:sdk:1.1.5'
|
||||
implementation 'io.github.wulkanowy:sdk:<version>'
|
||||
}
|
||||
```
|
||||
|
|
166
build.gradle
166
build.gradle
|
@ -1,64 +1,107 @@
|
|||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.4.31' apply false
|
||||
id "org.jlleitschuh.gradle.ktlint" version "9.2.1"
|
||||
id 'com.jfrog.bintray' version '1.8.5'
|
||||
alias(libs.plugins.kotlin) apply false
|
||||
alias(libs.plugins.ksp) apply false
|
||||
alias(libs.plugins.serialization)
|
||||
id "org.jlleitschuh.gradle.ktlint" version "12.1.0"
|
||||
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
|
||||
id 'ru.vyarus.mkdocs' version '3.0.0'
|
||||
}
|
||||
mkdocs.sourcesDir = 'docs'
|
||||
|
||||
ext {
|
||||
PUBLISH_VERSION = '1.1.5'
|
||||
SITE_URL = 'https://github.com/wulkanowy/sdk'
|
||||
GIT_URL = 'https://github.com/wulkanowy/sdk.git'
|
||||
|
||||
jspoon = "1.3.2"
|
||||
okhttp3 = "3.12.13"
|
||||
retrofit = "2.6.4"
|
||||
slf4j = "1.7.30"
|
||||
jsoup = "1.17.2"
|
||||
slf4j = "2.0.12"
|
||||
moshi = "1.13.0"
|
||||
}
|
||||
|
||||
version = "2.7.0"
|
||||
group = "io.github.wulkanowy"
|
||||
|
||||
nexusPublishing {
|
||||
repositories {
|
||||
sonatype {
|
||||
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
|
||||
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
|
||||
username = System.getenv("MAVEN_USERNAME")
|
||||
password = System.getenv("MAVEN_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'kotlinx-serialization'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.slf4j:slf4j-api:$slf4j"
|
||||
testImplementation "org.slf4j:slf4j-simple:$slf4j"
|
||||
|
||||
implementation platform(libs.okhttp.bom)
|
||||
}
|
||||
|
||||
version = PUBLISH_VERSION
|
||||
group = "io.github.wulkanowy"
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv('BINTRAY_USER')
|
||||
key = System.getenv('BINTRAY_KEY')
|
||||
configurations = ['archives']
|
||||
publishing {
|
||||
publications {
|
||||
sdk(MavenPublication) {
|
||||
from components.java
|
||||
version = rootProject.version
|
||||
|
||||
pkg {
|
||||
repo = 'wulkanowy'
|
||||
name = 'sdk'
|
||||
desc = 'Unified way of retrieving data from the UONET+ register through mobile api and scraping api'
|
||||
pom {
|
||||
name = 'VULCAN UONET+ SDK'
|
||||
description = 'Unified way of retrieving data from the UONET+ register through mobile api and scraping api'
|
||||
url = 'https://github.com/wulkanowy/sdk'
|
||||
licenses {
|
||||
license {
|
||||
name = 'The Apache License, Version 2.0'
|
||||
url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = 'mklkj'
|
||||
name = 'Mikołaj Pich'
|
||||
email = 'm.pich@outlook.com'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
connection = 'https://github.com/wulkanowy/sdk.git'
|
||||
developerConnection = 'git@github.com:wulkanowy/sdk.git'
|
||||
url = 'https://github.com/wulkanowy/sdk'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
websiteUrl = 'https://github.com/wulkanowy/sdk'
|
||||
issueTrackerUrl = 'https://github.com/wulkanowy/sdk/issues'
|
||||
vcsUrl = 'https://github.com/wulkanowy/sdk.git'
|
||||
licenses = ['Apache-2.0']
|
||||
userOrg = 'wulkanowy'
|
||||
labels = ['wulkanowy', 'sdk']
|
||||
publicDownloadNumbers = true
|
||||
publish = true
|
||||
if (System.getenv("MAVEN_SIGNING_KEY")) {
|
||||
signing {
|
||||
def signingKey = System.getenv("MAVEN_SIGNING_KEY") ?: ""
|
||||
def signingPassword = System.getenv("MAVEN_SIGNING_PASSWORD")
|
||||
useInMemoryPgpKeys(new String(signingKey.decodeBase64()), signingPassword)
|
||||
sign publishing.publications.sdk
|
||||
}
|
||||
}
|
||||
|
||||
version {
|
||||
name = PUBLISH_VERSION
|
||||
vcsTag = PUBLISH_VERSION
|
||||
released = new Date()
|
||||
javadoc {
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
options.addBooleanOption('html5', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,69 +111,56 @@ subprojects {
|
|||
apply plugin: 'jacoco'
|
||||
|
||||
ktlint {
|
||||
additionalEditorconfigFile = file(".editorconfig")
|
||||
// additionalEditorconfigFile.set(file(".editorconfig"))
|
||||
disabledRules = [
|
||||
"no-wildcard-imports",
|
||||
"import-ordering",
|
||||
"max-line-length"
|
||||
"max-line-length",
|
||||
"multiline-if-else"
|
||||
]
|
||||
filter {
|
||||
exclude { element -> element.file.path.contains("generated/") }
|
||||
}
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.6"
|
||||
javaParameters = true
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of("11"))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
|
||||
implementation libs.coroutines.core
|
||||
|
||||
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp3"
|
||||
implementation "com.squareup.okhttp3:logging-interceptor"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
|
||||
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp3"
|
||||
testImplementation "com.squareup.retrofit2:retrofit-mock:$retrofit"
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver"
|
||||
testImplementation libs.retrofit.mock
|
||||
testImplementation libs.coroutines.test
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
reports {
|
||||
xml.enabled true
|
||||
xml.getRequired().set(true)
|
||||
}
|
||||
}
|
||||
jacoco {
|
||||
toolVersion "0.8.10"
|
||||
}
|
||||
|
||||
test {
|
||||
testLogging.showStandardStreams = false
|
||||
}
|
||||
|
||||
group = "io.github.wulkanowy.sdk"
|
||||
if (project.plugins.hasPlugin('java')) {
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":sdk")
|
||||
compile project(":sdk-mobile")
|
||||
compile project(":sdk-scrapper")
|
||||
api project(":sdk")
|
||||
api project(":sdk-hebe")
|
||||
api project(":sdk-scrapper")
|
||||
|
||||
compile "com.squareup.okhttp3:okhttp:$okhttp3"
|
||||
api "com.squareup.okhttp3:okhttp"
|
||||
}
|
||||
|
|
26
docs/docs/about/history.md
Normal file
26
docs/docs/about/history.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
### 2.0.6 (2023.05.23)
|
||||
|
||||
* dodanie rozpoznawania strony błędu z aktualizacją bazy danych
|
||||
|
||||
### 2.0.5 (2023.05.23)
|
||||
|
||||
* aktualizacja retrofita do 2.10.0-SNAPSHOT, żeby naprawić błędy spowodowane przez R8 full mode w aplikacji
|
||||
|
||||
### 2.0.4 (2023.05.22)
|
||||
|
||||
* migracja z migbase64 na kotlin.io.encoding.Base64
|
||||
* aktualizacja kotlina do 1.8.21
|
||||
* wsparcie dla rozpoznawania nowych stron błędów z przerwą techniczną
|
||||
|
||||
### 2.0.3 (2023.05.12)
|
||||
|
||||
* fix autoryzacji poprzez dodanie brakujących nagłówków i ciasteczek do żądania z autoryzacją
|
||||
|
||||
### 2.0.1 (2023.05.12)
|
||||
|
||||
* fix pobierania zadań domowych z załącznikami, gdzie dziennik zaczął zwracać mniej danych niż kiedyś
|
||||
* dodanie metod umożliwiających sprawdzenie, czy uczeń został zautoryzowany oraz wykonanie jego autoryzacji w razie potrzeby
|
||||
|
||||
### 2.0.0 (2023.05.07)
|
||||
|
||||
* *Wersja bazowa*
|
49
docs/docs/guide/grades.md
Normal file
49
docs/docs/guide/grades.md
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Oceny
|
||||
|
||||
Poniżej przedstawiamy przykład pobrania ocen przez nasze Sdk, od początkowego logowania, przez wybór ucznia aż do wyświetlenia listy wszystkich ocen z ostatniego semestru wybranego ucznia.
|
||||
|
||||
!!! warning
|
||||
Nie wykonuj za każdym razem wyszukiwania listy uczniów — trwa to długo i nie ma z tego żadnego pożytku.
|
||||
Zamiast tego zapisz gdzieś wybrany `symbol`, `schoolSymbol`, `studentId`, `diaryId` oraz `semesterId` i używaj tych zapisanych danych do późniejszego ustawiania Sdk.
|
||||
|
||||
```kotlin
|
||||
// ustawiamy dane logowania
|
||||
val userEmail = "jan@fakelog.cf"
|
||||
val userPassword = "jan123"
|
||||
val host = "https://fakelog.cf/"
|
||||
|
||||
// tworzymy obiekt Sdk i pobieramy listę dostępnych uczniów
|
||||
val sdk = Sdk()
|
||||
val registerUser: RegisterUser = sdk.getUserSubjectsFromScrapper(
|
||||
email = userEmail,
|
||||
password = userPassword,
|
||||
scrapperBaseUrl = host,
|
||||
)
|
||||
|
||||
// na potrzeby tego demo odfiltrowujemy puste symbole i szkoły bez aktywnych uczniów
|
||||
val registerSymbol = registerUser.symbols
|
||||
.filter { it.schools.isNotEmpty() }
|
||||
.first { it.schools.all { school -> school.subjects.isNotEmpty() } }
|
||||
val registerUnit = registerSymbol.schools.first()
|
||||
val registerStudent = registerUnit.subjects.filterIsInstance<RegisterStudent>().first()
|
||||
val semester = registerStudent.semesters.last()
|
||||
|
||||
// re-inicjalizujemy Sdk z wcześniej pozyskanymi danymi
|
||||
sdk.apply {
|
||||
email = userEmail
|
||||
password = userPassword
|
||||
scrapperBaseUrl = host
|
||||
loginType = Sdk.ScrapperLoginType.valueOf(registerUser.loginType?.name!!) // todo: to akurat brzydkie, przeoczyłem to jakoś
|
||||
|
||||
symbol = registerSymbol.symbol
|
||||
schoolSymbol = registerUnit.schoolId
|
||||
studentId = registerStudent.studentId
|
||||
diaryId = semester.diaryId
|
||||
}
|
||||
|
||||
// pobieramy i wyświetlamy oceny z ostatniego semestru pierwszego dostępnego ucznia
|
||||
val grades = sdk.getGrades(semester.semesterId)
|
||||
grades.details.forEach {
|
||||
println("${it.entry} - ${it.date}")
|
||||
}
|
||||
```
|
34
docs/docs/guide/installation.md
Normal file
34
docs/docs/guide/installation.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Instalacja
|
||||
|
||||
[![Maven Central](https://img.shields.io/maven-central/v/io.github.wulkanowy/sdk?style=flat-square)](https://search.maven.org/artifact/io.github.wulkanowy/sdk)
|
||||
|
||||
Ostatnią stabilną wersję SDK możesz łatwo pobrać z repozytorium Maven Central:
|
||||
|
||||
```groovy
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'io.github.wulkanowy:sdk:2.0.6' // lub nowsza wersja, patrz na badge wyżej
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.wulkanowy/sdk?server=https%3A%2F%2Fs01.oss.sonatype.org&style=flat-square)](https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/wulkanowy/sdk/)
|
||||
|
||||
W razie potrzeby możesz też pobrać wersję SNAPSHOT zawierającą jeszcze niewydane zmiany, które znajdą się w następnej wersji:
|
||||
|
||||
```
|
||||
allprojects {
|
||||
repositories {
|
||||
...
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'io.github.wulkanowy:sdk:2.0.7-SNAPSHOT' // lub nowsza wersja, patrz na badge powyżej
|
||||
}
|
||||
```
|
122
docs/docs/guide/registration.md
Normal file
122
docs/docs/guide/registration.md
Normal file
|
@ -0,0 +1,122 @@
|
|||
# Rejestracja
|
||||
|
||||
Zależnie od wybranego trybu "rejestracja" zachowuje się inaczej, lecz ostatecznie jej wynikiem jest zwrócenie listy uczniów podpiętych do konta.
|
||||
I tak dla trybu:
|
||||
|
||||
* SCRAPPER — SDK spróbuje wyszukać na ostatnich 10 symbolach, na które logował się użytkownik, wszystkich dostępnych uczniów
|
||||
* HEBE — zarejestrowane zostanie urządzenie przez "Mobilny dostęp" i zwróceni zostaną uczniowie z tylko z danego symbolu
|
||||
* HYBRID — połączenie obu metod — SDK zarejestruje urządzenie dla każdego z symboli
|
||||
|
||||
!!! note
|
||||
Każda z tych metod zwraca tę samą strukturę danych, czyli `RegisterUser`, w której znajdują się wszystkie potrzebne dane, by używać reszty SDK.
|
||||
|
||||
## Tryby działania
|
||||
|
||||
### SCRAPPER
|
||||
|
||||
Scrapper obsługuje wszystkie obecnie znane strony logowania do różnych _odmian_ dziennika UONET+.
|
||||
W niektórych odmianach zamiast emaila stosuje się przyznany login (np. JANKOWA12).
|
||||
|
||||
Opis parametrów:
|
||||
|
||||
* `email` — adres e-mail użytkownika w przypadku odmiany vulcan.net.pl, w przypadku innych przydzielony login
|
||||
* `password` — hasło użytkownika
|
||||
* `scrapperBaseUrl` — adres bazowy odmiany dziennika. W większości przypadków będzie to `https://vulcan.net.pl/`, ale mogą być też inne, np. `https://opolska.eszkola.pl/`
|
||||
* `symbol` — opcjonalne (domyślnie `Default`). Symbol, od którego SDK będzie rozpoczynało przeszukiwanie dziennika.
|
||||
|
||||
!!! warning
|
||||
Jeśli używasz innej odmiany niż `vulcan.net.pl` to zawsze podawaj konkretny symbol, inaczej SDK prawdopodobnie niczego nie znajdzie.
|
||||
|
||||
```kotlin
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
|
||||
val sdk = Sdk()
|
||||
val registerUser: RegisterUser = sdk.getUserSubjectsFromScrapper(
|
||||
email = "jan@fakelog.cf",
|
||||
password = "jan123",
|
||||
scrapperBaseUrl = "https://fakelog.cf/",
|
||||
symbol = "powiatwulkanowy",
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
### HEBE
|
||||
|
||||
Hebe, dzięki swojej koncepcji wspiera i póki będzie istnieć, to będzie wspierać wszystkie odmiany dziennika.
|
||||
Z tego powodu wygrywa z trybem SCRAPPER pod względem stabilności i odporności na możliwe zmiany.
|
||||
|
||||
!!! warning
|
||||
Obsługa trybu HEBE jest w tej chwili mocno wybrakowana.
|
||||
|
||||
By zdobyć token, pin i symbol musisz ręcznie [zarejestrować urządzenie](https://wulkanowy.github.io/czesto-zadawane-pytania/co-to-jest-symbol).
|
||||
|
||||
`FirebaseToken` jest opcjonalnym parametrem, gdzie można przekazać... firebase token, używany do wysyłania powiadomień.
|
||||
|
||||
```kotlin
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
|
||||
val sdk = Sdk()
|
||||
val registerUser: RegisterUser = sdk.getStudentsFromHebe(
|
||||
token = "FK100000",
|
||||
pin = "999999",
|
||||
symbol = "powiatwulkanowy",
|
||||
firebaseToken = null,
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
### HYBRID
|
||||
|
||||
Tryb hybrydowy to specjalny tryb, który pod spodem używa dwóch powyższych metod, tj. najpierw wyszukuje wszystkich uczniów przez scrapper, a następnie rejestruje dla każdego znalezionego symbolu po jednym urządzeniu mobilnym.
|
||||
Z tego powodu nie ma potrzeby ręcznego przekazywania tokenu i pinu, bo SDK zdobędzie je samodzielnie.
|
||||
|
||||
```kotlin
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
|
||||
val sdk = Sdk()
|
||||
val registerUser: RegisterUser = sdk.getStudentsHybrid(
|
||||
email = "jan@fakelog.cf",
|
||||
password = "jan123",
|
||||
scrapperBaseUrl = "https://fakelog.cf/",
|
||||
startSymbol = "powiatwulkanowy",
|
||||
firebaseToken = null,
|
||||
)
|
||||
```
|
||||
|
||||
## Struktura RegisterUser
|
||||
|
||||
`RegisterUser` ma budowę _hierarchiczną_, dzięki czemu odzwierciedla faktyczne zależności między kolejnymi poziomami dostępu do danych.
|
||||
|
||||
Rzeczona hierarchia wygląda następująco:
|
||||
|
||||
```
|
||||
RegisterUser
|
||||
RegisterSymbol
|
||||
RegisterUnit
|
||||
RegisterSubject
|
||||
- RegisterEmployee
|
||||
- RegisterStudent
|
||||
Semester
|
||||
```
|
||||
|
||||
### RegisterUser
|
||||
|
||||
Na szczycie tej hierarchii jest użytkownik, w którym dołączone podstawowe informacje o koncie, tj. użyty e-mail, faktyczny login, typ logowania (którego ma używać później SDK), wybrany tryb działania SDK, jak i symbole (`RegisterSymbol`).
|
||||
|
||||
### RegisterSymbol
|
||||
|
||||
Każdy użytkownik dziennika może mieć dostęp do danych na wielu symbolach (np. rodzic, którego jedno dziecko uczy się w szkole podstawowej w mieście powiatowym, a drugie dziecko w szkole średniej w tym samym mieście).
|
||||
|
||||
Oprócz informacji o samym symbolu znajduje się tutaj informacja o możliwym błędzie przy próbie dostępu (jeśli takowy wystąpił), imię i nazwisko użytkownika, dane wykorzystywane przez HEBE (tj. `keyId`, `privatePem` i `hebeBaseUrl`) oraz listę szkół, znajdujących się pod danym symbolem, a do których dostęp ma dany użytkownik.
|
||||
|
||||
### RegisterUnit
|
||||
|
||||
Każda szkoła (jednostka — `unit`) ma swój identyfikator (`schoolId`), nazwę długą i krótką (`schoolName` i `schoolShortName`), trochę idków różnych typów użytkowników, podobnie jak w `RegisterSymbol` pole na możliwe błędy oraz listę _subjectów_ (podmiotów?), którymi mogą być uczeń lub pracownik.
|
||||
|
||||
### RegisterSubject
|
||||
|
||||
`RegisterSubject` to interfejs, który ma dwie implementacje: `RegisterEmployee` oraz `RegisterStudent`.
|
||||
|
||||
Pierwszej można użyć, do pobrania informacji o pracowniku (np. nauczycielu), by móc dalej używać SDK np. do obsługi wiadomości dla takiego użytkownika.
|
||||
|
||||
Druga to uczeń, który oprócz takich podstawowych informacji jak imiona, nazwa klasy, id ucznia oraz klasy posiada również listę semestrów.
|
11
docs/docs/index.md
Normal file
11
docs/docs/index.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Witaj w Kotlin SDK dla VULCAN UONET+
|
||||
|
||||
[![Maven Central](https://img.shields.io/maven-central/v/io.github.wulkanowy/sdk?style=flat-square)](https://search.maven.org/artifact/io.github.wulkanowy/sdk)
|
||||
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.wulkanowy/sdk?server=https%3A%2F%2Fs01.oss.sonatype.org&style=flat-square)](https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/wulkanowy/sdk/)
|
||||
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
|
||||
|
||||
## Składniki SDK
|
||||
|
||||
- sdk-hebe — używa API "Hebe", którego używa oficjalna aplikacja "Dzienniczek VULCAN". W tej chwili posiada bardzo ograniczoną funkcjonalność
|
||||
- sdk-scrapper — jak wskazuje nazwa, "scrapuje" stronę www dziennika
|
||||
- sdk — łączy dwie powyższe metody w miarę spójny interfejs
|
105
docs/mkdocs.yml
Normal file
105
docs/mkdocs.yml
Normal file
|
@ -0,0 +1,105 @@
|
|||
site_name: VULCAN UONET+ SDK
|
||||
|
||||
# Meta tags (placed in header)
|
||||
site_description:
|
||||
#site_author: Your Name
|
||||
site_url: # https://github.com/wulkanowy/sdk
|
||||
|
||||
# Repository (add link to repository on each page)
|
||||
repo_name: sdk
|
||||
repo_url: https://github.com/wulkanowy/sdk
|
||||
edit_uri: edit/master/docs/docs/
|
||||
|
||||
#Copyright (shown at the footer)
|
||||
copyright: 'Copyright © 2023 Wulkanowy'
|
||||
|
||||
# Meterial theme
|
||||
theme:
|
||||
name: 'material'
|
||||
palette:
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
primary: red
|
||||
accent: red
|
||||
toggle:
|
||||
icon: material/brightness-7
|
||||
name: Switch to dark mode
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
primary: red
|
||||
accent: red
|
||||
toggle:
|
||||
icon: material/brightness-4
|
||||
name: Switch to light mode
|
||||
features:
|
||||
#- navigation.tabs
|
||||
#- navigation.tabs.sticky
|
||||
#- navigation.instant
|
||||
- navigation.tracking
|
||||
- navigation.top
|
||||
|
||||
plugins:
|
||||
- search
|
||||
# Required for variables support (https://github.com/rosscdh/mkdocs-markdownextradata-plugin)
|
||||
# - markdownextradata
|
||||
|
||||
extra:
|
||||
|
||||
# version:
|
||||
# provider: mike
|
||||
|
||||
social:
|
||||
- icon: fontawesome/brands/facebook
|
||||
link: https://facebook.com/wulkanowy
|
||||
- icon: fontawesome/brands/github
|
||||
link: https://github.com/wulkanowy
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/wulkanowy
|
||||
#
|
||||
# Google Analytics
|
||||
# analytics:
|
||||
# provider: google
|
||||
# property: UA-XXXXXXXX-X
|
||||
|
||||
markdown_extensions:
|
||||
# Python Markdown
|
||||
- abbr
|
||||
- admonition
|
||||
- attr_list
|
||||
- def_list
|
||||
- footnotes
|
||||
- meta
|
||||
- md_in_html
|
||||
- toc:
|
||||
permalink: true
|
||||
|
||||
# Python Markdown Extensions
|
||||
- pymdownx.arithmatex:
|
||||
generic: true
|
||||
- pymdownx.betterem:
|
||||
smart_enable: all
|
||||
- pymdownx.caret
|
||||
- pymdownx.details
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.highlight
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.keys
|
||||
- pymdownx.mark
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.tilde
|
||||
|
||||
nav:
|
||||
- Start: index.md
|
||||
- User guide:
|
||||
- Instalacja: guide/installation.md
|
||||
- Rejestracja: guide/registration.md
|
||||
- Oceny: guide/grades.md
|
||||
- O projekcie:
|
||||
- Historia wydań: about/history.md
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
288
gradlew
vendored
288
gradlew
vendored
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -17,67 +17,98 @@
|
|||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
@ -87,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
@ -98,7 +129,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
|
@ -106,80 +137,109 @@ location of your Java installation."
|
|||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
|
@ -14,7 +14,7 @@
|
|||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
@ -25,7 +25,8 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
|
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
|
2
jitpack.yml
Normal file
2
jitpack.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
jdk:
|
||||
- openjdk11
|
1164
sdk-hebe/api/sdk-hebe.api
Normal file
1164
sdk-hebe/api/sdk-hebe.api
Normal file
File diff suppressed because it is too large
Load diff
20
sdk-hebe/build.gradle
Normal file
20
sdk-hebe/build.gradle
Normal file
|
@ -0,0 +1,20 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.kotlin.jvm'
|
||||
alias(libs.plugins.validator)
|
||||
id 'jacoco'
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'io.github.wulkanowy.signer:hebe-jvm:0.1.0-SNAPSHOT'
|
||||
|
||||
implementation libs.retrofit.core
|
||||
implementation libs.retrofit.scalars
|
||||
implementation libs.retrofit.serialization
|
||||
|
||||
testImplementation "io.mockk:mockk-jvm:1.13.10"
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.ZoneId
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter.ofPattern
|
||||
import java.util.UUID
|
||||
|
||||
@Serializable
|
||||
internal data class ApiRequest<T>(
|
||||
|
||||
@SerialName("API")
|
||||
val apiVersion: Int = 1,
|
||||
|
||||
@SerialName("AppName")
|
||||
val appName: String = "DzienniczekPlus 2.0",
|
||||
|
||||
@SerialName("AppVersion")
|
||||
val appVersion: String = "22.09.02 (G)",
|
||||
|
||||
@SerialName("CertificateId")
|
||||
val certificateId: String,
|
||||
|
||||
@SerialName("Envelope")
|
||||
val envelope: T,
|
||||
|
||||
@SerialName("FirebaseToken")
|
||||
val firebaseToken: String,
|
||||
|
||||
@SerialName("RequestId")
|
||||
val requestId: String = UUID.randomUUID().toString(),
|
||||
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long = ZonedDateTime.now(ZoneId.of("GMT")).toInstant().toEpochMilli(),
|
||||
|
||||
@SerialName("TimestampFormatted")
|
||||
val timestampFormatted: String = ZonedDateTime.now(ZoneId.of("GMT")).format(ofPattern("yyyy-MM-dd hh:mm:ss")),
|
||||
)
|
|
@ -0,0 +1,39 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal class ApiResponse<T> {
|
||||
|
||||
@SerialName("Envelope")
|
||||
var envelope: T? = null
|
||||
|
||||
@SerialName("EnvelopeType")
|
||||
lateinit var envelopeType: String
|
||||
|
||||
@SerialName("InResponseTo")
|
||||
var inResponseTo: String? = null
|
||||
|
||||
@SerialName("RequestId")
|
||||
lateinit var requestId: String
|
||||
|
||||
@SerialName("Status")
|
||||
lateinit var status: Status
|
||||
|
||||
@SerialName("Timestamp")
|
||||
var timestamp: Long = 0
|
||||
|
||||
@SerialName("TimestampFormatted")
|
||||
lateinit var timestampFormatted: String
|
||||
|
||||
@Serializable
|
||||
data class Status(
|
||||
|
||||
@SerialName("Code")
|
||||
val code: Int,
|
||||
|
||||
@SerialName("Message")
|
||||
val message: String,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializer(forClass = LocalDate::class)
|
||||
internal object CustomDateAdapter : KSerializer<LocalDate> {
|
||||
|
||||
private const val DATE_FORMAT_1 = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||
private const val DATE_FORMAT_2 = "yyyy-MM-dd'T'HH:mm:ss.SSXXX"
|
||||
private const val DATE_FORMAT_3 = "yyyy-MM-dd'T'HH:mm:ss.SXXX"
|
||||
private const val DATE_FORMAT_4 = "yyyy-MM-dd'T'HH:mm:ssXXX"
|
||||
private const val DATE_FORMAT_5 = "yyyy-MM-dd HH:mm:ss"
|
||||
private const val DATE_FORMAT_6 = "yyyy-MM-dd"
|
||||
|
||||
private val formatter = DateTimeFormatter.ofPattern("[$DATE_FORMAT_1][$DATE_FORMAT_2][$DATE_FORMAT_3][$DATE_FORMAT_4][$DATE_FORMAT_5][$DATE_FORMAT_6]")
|
||||
|
||||
override fun deserialize(decoder: Decoder): LocalDate {
|
||||
val date = decoder.decodeString()
|
||||
|
||||
return LocalDate.parse(date, formatter)
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: LocalDate) {
|
||||
encoder.encodeString(value.format(formatter))
|
||||
}
|
||||
}
|
151
sdk-hebe/src/main/kotlin/io/github/wulkanowy/sdk/hebe/Hebe.kt
Normal file
151
sdk-hebe/src/main/kotlin/io/github/wulkanowy/sdk/hebe/Hebe.kt
Normal file
|
@ -0,0 +1,151 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.models.Exam
|
||||
import io.github.wulkanowy.sdk.hebe.models.Grade
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeAverage
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeSummary
|
||||
import io.github.wulkanowy.sdk.hebe.register.RegisterDevice
|
||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||
import io.github.wulkanowy.sdk.hebe.repository.RepositoryManager
|
||||
import io.github.wulkanowy.signer.hebe.generateKeyPair
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import java.time.LocalDate
|
||||
|
||||
class Hebe {
|
||||
|
||||
private val resettableManager = resettableManager()
|
||||
|
||||
var logLevel = HttpLoggingInterceptor.Level.BASIC
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var keyId = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var privatePem = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var baseUrl = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var schoolId = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var pupilId = -1
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var deviceModel = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
private val appInterceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf()
|
||||
|
||||
fun addInterceptor(interceptor: Interceptor, network: Boolean = false) {
|
||||
appInterceptors.add(interceptor to network)
|
||||
}
|
||||
|
||||
private val serviceManager by resettableLazy(resettableManager) {
|
||||
RepositoryManager(
|
||||
logLevel = logLevel,
|
||||
keyId = keyId,
|
||||
privatePem = privatePem,
|
||||
deviceModel = deviceModel,
|
||||
).apply {
|
||||
appInterceptors.forEach { (interceptor, isNetwork) ->
|
||||
setInterceptor(interceptor, isNetwork)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val routes by resettableLazy(resettableManager) { serviceManager.getRoutesRepository() }
|
||||
|
||||
private val studentRepository by resettableLazy(resettableManager) {
|
||||
serviceManager.getStudentRepository(
|
||||
baseUrl = baseUrl,
|
||||
schoolId = schoolId,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun register(token: String, pin: String, symbol: String, firebaseToken: String? = null): RegisterDevice {
|
||||
val (publicPem, privatePem, publicHash) = generateKeyPair()
|
||||
|
||||
this.keyId = publicHash
|
||||
this.privatePem = privatePem
|
||||
|
||||
val envelope = serviceManager.getRegisterRepository(
|
||||
baseUrl = routes.getRouteByToken(token),
|
||||
symbol = symbol,
|
||||
).register(
|
||||
firebaseToken = firebaseToken,
|
||||
token = token,
|
||||
pin = pin,
|
||||
certificatePem = publicPem,
|
||||
certificateId = publicHash,
|
||||
deviceModel = deviceModel,
|
||||
)
|
||||
|
||||
return RegisterDevice(
|
||||
loginId = envelope.loginId,
|
||||
restUrl = envelope.restUrl,
|
||||
userLogin = envelope.userLogin,
|
||||
userName = envelope.userName,
|
||||
certificateHash = publicHash,
|
||||
privatePem = privatePem,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getStudents(url: String): List<StudentInfo> {
|
||||
return serviceManager
|
||||
.getRegisterRepository(url)
|
||||
.getStudentInfo()
|
||||
}
|
||||
|
||||
suspend fun getGrades(periodId: Int): List<Grade> {
|
||||
return studentRepository.getGrades(
|
||||
pupilId = pupilId,
|
||||
periodId = periodId,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getGradesSummary(periodId: Int): List<GradeSummary> {
|
||||
return studentRepository.getGradesSummary(
|
||||
pupilId = pupilId,
|
||||
periodId = periodId,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getGradesAverage(periodId: Int): List<GradeAverage> {
|
||||
return studentRepository.getGradesAverage(
|
||||
pupilId = pupilId,
|
||||
periodId = periodId,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getExams(startDate: LocalDate, endDate: LocalDate): List<Exam> {
|
||||
return studentRepository.getExams(
|
||||
pupilId = pupilId,
|
||||
startDate = startDate,
|
||||
endDate = endDate,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
internal fun <T> ApiResponse<T>.getEnvelopeOrThrowError(): T? {
|
||||
if (envelope == null) {
|
||||
when (status.code) {
|
||||
// 100 -> "Użytkownik nie jest uprawniony do przeglądania żądanych danych"
|
||||
// todo: add more codes
|
||||
else -> error("Unknown error: ${status.message}")
|
||||
}
|
||||
}
|
||||
return envelope
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.wulkanowy.sdk.mobile
|
||||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import java.util.LinkedList
|
||||
import kotlin.reflect.KProperty
|
||||
|
@ -6,7 +6,7 @@ import kotlin.reflect.KProperty
|
|||
/**
|
||||
* see https://stackoverflow.com/a/35757638/6695449
|
||||
*/
|
||||
class ResettableLazyManager {
|
||||
internal class ResettableLazyManager {
|
||||
// we synchronize to make sure the timing of a reset() call and new inits do not collide
|
||||
val managedDelegates = LinkedList<Resettable>()
|
||||
|
||||
|
@ -24,11 +24,11 @@ class ResettableLazyManager {
|
|||
}
|
||||
}
|
||||
|
||||
interface Resettable {
|
||||
internal interface Resettable {
|
||||
fun reset()
|
||||
}
|
||||
|
||||
class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: () -> PROPTYPE) : Resettable {
|
||||
internal class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: () -> PROPTYPE) : Resettable {
|
||||
@Volatile
|
||||
var lazyHolder = makeInitBlock()
|
||||
|
||||
|
@ -48,8 +48,8 @@ class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: ()
|
|||
}
|
||||
}
|
||||
|
||||
fun <PROPTYPE> resettableLazy(manager: ResettableLazyManager, init: () -> PROPTYPE): ResettableLazy<PROPTYPE> {
|
||||
internal fun <PROPTYPE> resettableLazy(manager: ResettableLazyManager, init: () -> PROPTYPE): ResettableLazy<PROPTYPE> {
|
||||
return ResettableLazy(manager, init)
|
||||
}
|
||||
|
||||
fun resettableManager(): ResettableLazyManager = ResettableLazyManager()
|
||||
internal fun resettableManager(): ResettableLazyManager = ResettableLazyManager()
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.wulkanowy.sdk.hebe.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class InvalidPinException : IOException()
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
package io.github.wulkanowy.sdk.hebe.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.wulkanowy.sdk.hebe.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class InvalidTokenException(message: String) : IOException(message)
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.wulkanowy.sdk.hebe.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class TokenDeadException : IOException()
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.wulkanowy.sdk.hebe.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class UnknownTokenException(message: String) : IOException(message)
|
|
@ -0,0 +1,11 @@
|
|||
package io.github.wulkanowy.sdk.hebe.interceptor
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
internal class ErrorInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
return chain.proceed(chain.request())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package io.github.wulkanowy.sdk.hebe.interceptor
|
||||
|
||||
import io.github.wulkanowy.signer.hebe.getSignatureHeaders
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okio.Buffer
|
||||
import java.nio.charset.Charset
|
||||
import java.time.ZoneId
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
internal class SignInterceptor(
|
||||
private val keyId: String,
|
||||
private val privatePem: String,
|
||||
private val deviceModel: String,
|
||||
) : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val original = chain.request()
|
||||
val request = original.newBuilder()
|
||||
|
||||
request.header("User-Agent", "Dart/2.10 (dart:io)")
|
||||
request.header("vOS", "Android")
|
||||
request.header("vDeviceModel", deviceModel)
|
||||
request.header("vAPI", "1")
|
||||
|
||||
if (privatePem.isNotBlank()) {
|
||||
val signatureHeaders = Buffer().run {
|
||||
original.body?.writeTo(this)
|
||||
getSignatureHeaders(
|
||||
keyId = keyId,
|
||||
privatePem = privatePem,
|
||||
body = readString(Charset.defaultCharset()),
|
||||
requestPath = original.url.pathSegments.drop(1).joinToString("/"),
|
||||
timestamp = ZonedDateTime.now(ZoneId.of("GMT")),
|
||||
)
|
||||
}
|
||||
signatureHeaders.forEach { (key, value) ->
|
||||
request.header(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
return chain.proceed(request.method(original.method, original.body).build())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package io.github.wulkanowy.sdk.hebe.models
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.CustomDateAdapter
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.LocalDate
|
||||
|
||||
@Serializable
|
||||
data class Exam(
|
||||
@SerialName("Content")
|
||||
val content: String,
|
||||
@SerialName("Creator")
|
||||
val creator: Creator,
|
||||
@SerialName("DateCreated")
|
||||
val dateCreated: DateCreated,
|
||||
@SerialName("DateModify")
|
||||
val dateModify: DateModify,
|
||||
@SerialName("Deadline")
|
||||
val deadline: Deadline,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("PupilId")
|
||||
val pupilId: Int,
|
||||
@SerialName("Subject")
|
||||
val subject: Subject,
|
||||
@SerialName("Type")
|
||||
val type: String,
|
||||
) {
|
||||
@Serializable
|
||||
data class Creator(
|
||||
@SerialName("DisplayName")
|
||||
val displayName: String,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class DateCreated(
|
||||
@SerialName("Date")
|
||||
@Serializable(with = CustomDateAdapter::class)
|
||||
val date: LocalDate,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class DateModify(
|
||||
@SerialName("Date")
|
||||
@Serializable(with = CustomDateAdapter::class)
|
||||
val date: LocalDate,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Deadline(
|
||||
@SerialName("Date")
|
||||
@Serializable(with = CustomDateAdapter::class)
|
||||
val date: LocalDate,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Subject(
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Kod")
|
||||
val kod: String,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Position")
|
||||
val position: Int,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package io.github.wulkanowy.sdk.hebe.models
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Grade(
|
||||
@SerialName("Column")
|
||||
val column: Column,
|
||||
@SerialName("Comment")
|
||||
val comment: String,
|
||||
@SerialName("Content")
|
||||
val content: String,
|
||||
@SerialName("ContentRaw")
|
||||
val contentRaw: String,
|
||||
@SerialName("Creator")
|
||||
val creator: Creator,
|
||||
@SerialName("DateCreated")
|
||||
val dateCreated: DateCreated,
|
||||
@SerialName("DateModify")
|
||||
val dateModify: DateModify,
|
||||
// @SerialName("Denominator")
|
||||
// val denominator: Any?,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Modifier")
|
||||
val modifier: Modifier,
|
||||
// @SerialName("Numerator")
|
||||
// val numerator: Any?,
|
||||
@SerialName("PupilId")
|
||||
val pupilId: Int,
|
||||
@SerialName("Value")
|
||||
val value: Double? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class Column(
|
||||
@SerialName("Category")
|
||||
val category: Category? = null,
|
||||
@SerialName("Code")
|
||||
val code: String,
|
||||
@SerialName("Color")
|
||||
val color: Int,
|
||||
@SerialName("Group")
|
||||
val group: String? = null,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Number")
|
||||
val number: Int,
|
||||
@SerialName("PeriodId")
|
||||
val periodId: Int,
|
||||
@SerialName("Subject")
|
||||
val subject: Subject,
|
||||
@SerialName("Weight")
|
||||
val weight: Double,
|
||||
) {
|
||||
@Serializable
|
||||
data class Category(
|
||||
@SerialName("Code")
|
||||
val code: String,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Subject(
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Kod")
|
||||
val kod: String,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Position")
|
||||
val position: Int,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Creator(
|
||||
@SerialName("DisplayName")
|
||||
val displayName: String,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class DateCreated(
|
||||
@SerialName("Date")
|
||||
val date: String,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class DateModify(
|
||||
@SerialName("Date")
|
||||
val date: String,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Modifier(
|
||||
@SerialName("DisplayName")
|
||||
val displayName: String,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.github.wulkanowy.sdk.hebe.models
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class GradeAverage(
|
||||
@SerialName("Average")
|
||||
val average: String,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("PeriodId")
|
||||
val periodId: Int,
|
||||
// @SerialName("Points")
|
||||
// val points: Any?,
|
||||
@SerialName("PupilId")
|
||||
val pupilId: Int,
|
||||
@SerialName("Subject")
|
||||
val subject: Subject,
|
||||
) {
|
||||
@Serializable
|
||||
data class Subject(
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Kod")
|
||||
val kod: String,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Position")
|
||||
val position: Int,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package io.github.wulkanowy.sdk.hebe.models
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class GradeSummary(
|
||||
@SerialName("DateModify")
|
||||
val dateModify: DateModify,
|
||||
@SerialName("Entry_1")
|
||||
val entry1: String? = null,
|
||||
@SerialName("Entry_2")
|
||||
val entry2: String? = null,
|
||||
// @SerialName("Entry_3")
|
||||
// val entry3: Any?,
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("PeriodId")
|
||||
val periodId: Int,
|
||||
@SerialName("PupilId")
|
||||
val pupilId: Int,
|
||||
@SerialName("Subject")
|
||||
val subject: Subject,
|
||||
) {
|
||||
@Serializable
|
||||
data class DateModify(
|
||||
@SerialName("Date")
|
||||
val date: String,
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Subject(
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
@SerialName("Key")
|
||||
val key: String,
|
||||
@SerialName("Kod")
|
||||
val kod: String,
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
@SerialName("Position")
|
||||
val position: Int,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package io.github.wulkanowy.sdk.hebe.register
|
||||
|
||||
data class RegisterDevice(
|
||||
val loginId: Int,
|
||||
val restUrl: String,
|
||||
val userLogin: String,
|
||||
val userName: String,
|
||||
val certificateHash: String,
|
||||
val privatePem: String,
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
package io.github.wulkanowy.sdk.hebe.register
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.UUID
|
||||
|
||||
@Serializable
|
||||
internal data class RegisterRequest(
|
||||
|
||||
@SerialName("Certificate")
|
||||
val certificate: String,
|
||||
|
||||
@SerialName("CertificateThumbprint")
|
||||
val certificateThumbprint: String,
|
||||
|
||||
@SerialName("CertificateType")
|
||||
val certificateType: String = "RSA_PEM",
|
||||
|
||||
@SerialName("DeviceModel")
|
||||
val deviceModel: String,
|
||||
|
||||
@SerialName("OS")
|
||||
val os: String = "Android",
|
||||
|
||||
@SerialName("PIN")
|
||||
val pin: String,
|
||||
|
||||
@SerialName("SecurityToken")
|
||||
val securityToken: String,
|
||||
|
||||
@SerialName("SelfIdentifier")
|
||||
val selfIdentifier: String = UUID.randomUUID().toString(),
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
package io.github.wulkanowy.sdk.hebe.register
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal data class RegisterResponse(
|
||||
|
||||
@SerialName("LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@SerialName("RestURL")
|
||||
val restUrl: String,
|
||||
|
||||
@SerialName("UserLogin")
|
||||
val userLogin: String,
|
||||
|
||||
@SerialName("UserName")
|
||||
val userName: String,
|
||||
)
|
|
@ -0,0 +1,277 @@
|
|||
package io.github.wulkanowy.sdk.hebe.register
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
class StudentInfo(
|
||||
|
||||
@SerialName("Capabilities")
|
||||
val capabilities: List<String>,
|
||||
|
||||
@SerialName("ClassDisplay")
|
||||
val classDisplay: String,
|
||||
|
||||
@SerialName("ConstituentUnit")
|
||||
val constituentUnit: ConstituentUnit,
|
||||
|
||||
@SerialName("Educators")
|
||||
val educators: List<Educator>,
|
||||
|
||||
@SerialName("FullSync")
|
||||
val fullSync: Boolean,
|
||||
|
||||
@SerialName("InfoDisplay")
|
||||
val infoDisplay: String,
|
||||
|
||||
@SerialName("Journal")
|
||||
val journal: Journal,
|
||||
|
||||
@SerialName("Login")
|
||||
val login: Login,
|
||||
|
||||
@SerialName("Partition")
|
||||
val partition: String,
|
||||
|
||||
@SerialName("Periods")
|
||||
val periods: List<Period>,
|
||||
|
||||
@SerialName("Pupil")
|
||||
val pupil: Pupil,
|
||||
|
||||
@SerialName("SenderEntry")
|
||||
val senderEntry: SenderEntry,
|
||||
|
||||
@SerialName("TopLevelPartition")
|
||||
val topLevelPartition: String,
|
||||
|
||||
@SerialName("Unit")
|
||||
val unit: Unit,
|
||||
) {
|
||||
|
||||
@Serializable
|
||||
data class ConstituentUnit(
|
||||
|
||||
@SerialName("Address")
|
||||
val address: String,
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
|
||||
@SerialName("Patron")
|
||||
val patron: String,
|
||||
|
||||
@SerialName("SchoolTopic")
|
||||
val schoolTopic: String,
|
||||
|
||||
@SerialName("Short")
|
||||
val short: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Educator(
|
||||
|
||||
@SerialName("Id")
|
||||
val id: String,
|
||||
|
||||
@SerialName("Initials")
|
||||
val initials: String,
|
||||
|
||||
@SerialName("LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
|
||||
@SerialName("Roles")
|
||||
val roles: List<Role>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Role(
|
||||
|
||||
@SerialName("Address")
|
||||
val address: String,
|
||||
|
||||
@SerialName("AddressHash")
|
||||
val addressHash: String,
|
||||
|
||||
@SerialName("ClassSymbol")
|
||||
val classSymbol: String,
|
||||
|
||||
@SerialName("ConstituentUnitSymbol")
|
||||
val constituentUnitSymbol: String,
|
||||
|
||||
@SerialName("Initials")
|
||||
val initials: String,
|
||||
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
|
||||
@SerialName("RoleName")
|
||||
val roleName: String,
|
||||
|
||||
@SerialName("RoleOrder")
|
||||
val roleOrder: Int,
|
||||
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
|
||||
@SerialName("UnitSymbol")
|
||||
val unitSymbol: String? = null,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Journal(
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("YearStart")
|
||||
val yearStart: PeriodDate,
|
||||
|
||||
@SerialName("YearEnd")
|
||||
val yearEnd: PeriodDate,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PeriodDate(
|
||||
|
||||
@SerialName("Date")
|
||||
val date: String,
|
||||
|
||||
@SerialName("DateDisplay")
|
||||
val dateDisplay: String,
|
||||
|
||||
@SerialName("Time")
|
||||
val time: String,
|
||||
|
||||
@SerialName("Timestamp")
|
||||
val timestamp: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Login(
|
||||
|
||||
@SerialName("DisplayName")
|
||||
val displayName: String,
|
||||
|
||||
@SerialName("FirstName")
|
||||
val firstName: String,
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("LoginRole")
|
||||
val loginRole: String,
|
||||
|
||||
@SerialName("SecondName")
|
||||
val secondName: String?,
|
||||
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
|
||||
@SerialName("Value")
|
||||
val value: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Period(
|
||||
|
||||
@SerialName("Current")
|
||||
val current: Boolean,
|
||||
|
||||
@SerialName("End")
|
||||
val end: PeriodDate,
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("Last")
|
||||
val last: Boolean,
|
||||
|
||||
@SerialName("Level")
|
||||
val level: Int,
|
||||
|
||||
@SerialName("Number")
|
||||
val number: Int,
|
||||
|
||||
@SerialName("Start")
|
||||
val start: PeriodDate,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Pupil(
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("LoginId")
|
||||
val loginId: Int = -1,
|
||||
|
||||
@SerialName("LoginValue")
|
||||
val loginValue: String? = null,
|
||||
|
||||
@SerialName("FirstName")
|
||||
val firstName: String,
|
||||
|
||||
@SerialName("SecondName")
|
||||
val secondName: String = "",
|
||||
|
||||
@SerialName("Surname")
|
||||
val surname: String,
|
||||
|
||||
@SerialName("Sex")
|
||||
val sex: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SenderEntry(
|
||||
|
||||
@SerialName("Address")
|
||||
val address: String,
|
||||
|
||||
@SerialName("AddressHash")
|
||||
val addressHash: String,
|
||||
|
||||
@SerialName("Initials")
|
||||
val initials: String,
|
||||
|
||||
@SerialName("LoginId")
|
||||
val loginId: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Unit(
|
||||
|
||||
@SerialName("Address")
|
||||
val address: String,
|
||||
|
||||
@SerialName("DisplayName")
|
||||
val displayName: String,
|
||||
|
||||
@SerialName("Id")
|
||||
val id: Int,
|
||||
|
||||
@SerialName("Name")
|
||||
val name: String,
|
||||
|
||||
@SerialName("Patron")
|
||||
val patron: String,
|
||||
|
||||
@SerialName("RestURL")
|
||||
val restUrl: String,
|
||||
|
||||
@SerialName("Short")
|
||||
val short: String,
|
||||
|
||||
@SerialName("Symbol")
|
||||
val symbol: String,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package io.github.wulkanowy.sdk.hebe.repository
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.ApiRequest
|
||||
import io.github.wulkanowy.sdk.hebe.ApiResponse
|
||||
import io.github.wulkanowy.sdk.hebe.exception.InvalidSymbolException
|
||||
import io.github.wulkanowy.sdk.hebe.getEnvelopeOrThrowError
|
||||
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||
import io.github.wulkanowy.sdk.hebe.service.RegisterService
|
||||
import retrofit2.HttpException
|
||||
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|
||||
internal class RegisterRepository(private val service: RegisterService) {
|
||||
|
||||
suspend fun register(
|
||||
token: String,
|
||||
pin: String,
|
||||
deviceModel: String,
|
||||
certificatePem: String,
|
||||
certificateId: String,
|
||||
firebaseToken: String?,
|
||||
): RegisterResponse = registerDevice(
|
||||
privateKey = certificatePem,
|
||||
certificateId = certificateId,
|
||||
deviceModel = deviceModel,
|
||||
firebaseToken = firebaseToken.orEmpty(),
|
||||
pin = pin,
|
||||
token = token,
|
||||
).getEnvelopeOrThrowError()!!
|
||||
|
||||
private suspend fun registerDevice(
|
||||
privateKey: String,
|
||||
certificateId: String,
|
||||
deviceModel: String,
|
||||
firebaseToken: String,
|
||||
pin: String,
|
||||
token: String,
|
||||
): ApiResponse<RegisterResponse> = runCatching {
|
||||
service.registerDevice(
|
||||
ApiRequest(
|
||||
certificateId = certificateId,
|
||||
firebaseToken = firebaseToken,
|
||||
envelope = RegisterRequest(
|
||||
certificate = privateKey,
|
||||
certificateThumbprint = certificateId,
|
||||
deviceModel = deviceModel,
|
||||
pin = pin,
|
||||
securityToken = token,
|
||||
),
|
||||
),
|
||||
)
|
||||
}.onFailure {
|
||||
if (it is HttpException && it.code() == HTTP_INTERNAL_ERROR) {
|
||||
if ("ArgumentException" in it.response()?.errorBody()?.string().orEmpty()) {
|
||||
throw InvalidSymbolException()
|
||||
}
|
||||
}
|
||||
}.getOrThrow()
|
||||
|
||||
suspend fun getStudentInfo(): List<StudentInfo> {
|
||||
return service.getStudentsInfo().envelope!!
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package io.github.wulkanowy.sdk.hebe.repository
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.interceptor.ErrorInterceptor
|
||||
import io.github.wulkanowy.sdk.hebe.interceptor.SignInterceptor
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory
|
||||
import retrofit2.create
|
||||
|
||||
internal class RepositoryManager(
|
||||
private val keyId: String,
|
||||
private val privatePem: String,
|
||||
private val deviceModel: String,
|
||||
logLevel: HttpLoggingInterceptor.Level,
|
||||
) {
|
||||
|
||||
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf(
|
||||
HttpLoggingInterceptor().setLevel(logLevel) to true,
|
||||
ErrorInterceptor() to false,
|
||||
)
|
||||
|
||||
fun setInterceptor(interceptor: Interceptor, network: Boolean = false) {
|
||||
interceptors.add(0, interceptor to network)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private val json by lazy {
|
||||
Json {
|
||||
explicitNulls = false
|
||||
encodeDefaults = true
|
||||
ignoreUnknownKeys = true
|
||||
coerceInputValues = true
|
||||
isLenient = true
|
||||
}
|
||||
}
|
||||
|
||||
fun getRoutesRepository(): RoutingRulesRepository {
|
||||
return RoutingRulesRepository(
|
||||
getRetrofitBuilder(isJson = false, signInterceptor = false)
|
||||
.baseUrl("https://komponenty.vulcan.net.pl")
|
||||
.build()
|
||||
.create(),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStudentRepository(baseUrl: String, schoolId: String): StudentRepository = StudentRepository(
|
||||
getRetrofitBuilder(isJson = true, signInterceptor = true)
|
||||
.baseUrl("${baseUrl.removeSuffix("/")}/$schoolId/")
|
||||
.build()
|
||||
.create(),
|
||||
)
|
||||
|
||||
internal fun getRegisterRepository(baseUrl: String, symbol: String = ""): RegisterRepository = getRegisterRepository(
|
||||
baseUrl = "${baseUrl.removeSuffix("/")}/$symbol",
|
||||
)
|
||||
|
||||
private fun getRegisterRepository(baseUrl: String): RegisterRepository = RegisterRepository(
|
||||
getRetrofitBuilder(signInterceptor = true)
|
||||
.baseUrl("${baseUrl.removeSuffix("/")}/api/mobile/register/")
|
||||
.build()
|
||||
.create(),
|
||||
)
|
||||
|
||||
private fun getRetrofitBuilder(isJson: Boolean = true, signInterceptor: Boolean): Retrofit.Builder {
|
||||
return Retrofit.Builder()
|
||||
.apply {
|
||||
when {
|
||||
isJson -> addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
||||
else -> addConverterFactory(ScalarsConverterFactory.create())
|
||||
}
|
||||
}
|
||||
.client(
|
||||
OkHttpClient().newBuilder()
|
||||
.apply {
|
||||
if (signInterceptor) {
|
||||
addInterceptor(SignInterceptor(keyId, privatePem, deviceModel))
|
||||
}
|
||||
interceptors.forEach {
|
||||
when {
|
||||
it.second -> addNetworkInterceptor(it.first)
|
||||
else -> addInterceptor(it.first)
|
||||
}
|
||||
}
|
||||
}
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.github.wulkanowy.sdk.hebe.repository
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.exception.InvalidTokenException
|
||||
import io.github.wulkanowy.sdk.hebe.exception.UnknownTokenException
|
||||
import io.github.wulkanowy.sdk.hebe.service.RoutingRulesService
|
||||
|
||||
internal class RoutingRulesRepository(private val api: RoutingRulesService) {
|
||||
|
||||
suspend fun getRouteByToken(token: String): String {
|
||||
if (token.length < 4) throw InvalidTokenException("Token '$token' is too short")
|
||||
|
||||
val tokenSymbol = token.substring(0..2)
|
||||
|
||||
if ("FK1" == tokenSymbol) return "https://api.fakelog.cf"
|
||||
|
||||
return api.getRoutingRules()
|
||||
.split("\r?\n".toRegex())
|
||||
.singleOrNull { tokenSymbol == it.substringBefore(",") }
|
||||
?.substringAfter(",")
|
||||
?: throw UnknownTokenException("This token: '$token' is unsupported")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package io.github.wulkanowy.sdk.hebe.repository
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.getEnvelopeOrThrowError
|
||||
import io.github.wulkanowy.sdk.hebe.models.Exam
|
||||
import io.github.wulkanowy.sdk.hebe.models.Grade
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeAverage
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeSummary
|
||||
import io.github.wulkanowy.sdk.hebe.service.StudentService
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
internal class StudentRepository(private val studentService: StudentService) {
|
||||
|
||||
suspend fun getGrades(pupilId: Int, periodId: Int): List<Grade> {
|
||||
return studentService.getGrades(
|
||||
createQueryMap(pupilId = pupilId, periodId = periodId),
|
||||
).getEnvelopeOrThrowError().orEmpty()
|
||||
}
|
||||
|
||||
suspend fun getGradesSummary(pupilId: Int, periodId: Int): List<GradeSummary> {
|
||||
return studentService.getGradesSummary(
|
||||
createQueryMap(pupilId = pupilId, periodId = periodId),
|
||||
).getEnvelopeOrThrowError().orEmpty()
|
||||
}
|
||||
|
||||
suspend fun getGradesAverage(pupilId: Int, periodId: Int): List<GradeAverage> {
|
||||
return studentService.getGradesAverage(
|
||||
createQueryMap(pupilId = pupilId, periodId = periodId),
|
||||
).getEnvelopeOrThrowError().orEmpty()
|
||||
}
|
||||
|
||||
suspend fun getExams(pupilId: Int, startDate: LocalDate, endDate: LocalDate): List<Exam> {
|
||||
return studentService.getExams(
|
||||
createQueryMap(pupilId = pupilId, dateFrom = startDate),
|
||||
).getEnvelopeOrThrowError().orEmpty().filter {
|
||||
it.deadline.date in startDate..endDate
|
||||
}
|
||||
}
|
||||
|
||||
private fun createQueryMap(
|
||||
pupilId: Int,
|
||||
periodId: Int? = null,
|
||||
dateFrom: LocalDate? = null,
|
||||
dateTo: LocalDate? = null,
|
||||
): Map<String, Any?> = mapOf(
|
||||
"pupilId" to pupilId,
|
||||
"periodId" to periodId,
|
||||
"lastSyncDate" to "1970-01-01 01:00:00",
|
||||
"lastId" to Int.MIN_VALUE,
|
||||
"pageSize" to 500,
|
||||
"dateFrom" to dateFrom?.format(DateTimeFormatter.ISO_DATE),
|
||||
"dateTo" to dateTo?.format(DateTimeFormatter.ISO_DATE),
|
||||
).filterValues { it != null }
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.github.wulkanowy.sdk.hebe.service
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.ApiRequest
|
||||
import io.github.wulkanowy.sdk.hebe.ApiResponse
|
||||
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
|
||||
internal interface RegisterService {
|
||||
|
||||
@POST("new")
|
||||
suspend fun registerDevice(@Body request: ApiRequest<RegisterRequest>): ApiResponse<RegisterResponse>
|
||||
|
||||
@GET("hebe")
|
||||
suspend fun getStudentsInfo(): ApiResponse<List<StudentInfo>>
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package io.github.wulkanowy.sdk.mobile.service
|
||||
package io.github.wulkanowy.sdk.hebe.service
|
||||
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface RoutingRulesService {
|
||||
internal interface RoutingRulesService {
|
||||
|
||||
@GET("/UonetPlusMobile/RoutingRules.txt")
|
||||
suspend fun getRoutingRules(): String
|
|
@ -0,0 +1,25 @@
|
|||
package io.github.wulkanowy.sdk.hebe.service
|
||||
|
||||
import io.github.wulkanowy.sdk.hebe.ApiResponse
|
||||
import io.github.wulkanowy.sdk.hebe.models.Exam
|
||||
import io.github.wulkanowy.sdk.hebe.models.Grade
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeAverage
|
||||
import io.github.wulkanowy.sdk.hebe.models.GradeSummary
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.QueryMap
|
||||
|
||||
@JvmSuppressWildcards
|
||||
internal interface StudentService {
|
||||
|
||||
@GET("api/mobile/grade/byPupil")
|
||||
suspend fun getGrades(@QueryMap query: Map<String, Any?>): ApiResponse<List<Grade>>
|
||||
|
||||
@GET("api/mobile/grade/summary/byPupil")
|
||||
suspend fun getGradesSummary(@QueryMap query: Map<String, Any?>): ApiResponse<List<GradeSummary>>
|
||||
|
||||
@GET("api/mobile/grade/average/byPupil")
|
||||
suspend fun getGradesAverage(@QueryMap query: Map<String, Any?>): ApiResponse<List<GradeAverage>>
|
||||
|
||||
@GET("api/mobile/exam/byPupil")
|
||||
suspend fun getExams(@QueryMap query: Map<String, Any?>): ApiResponse<List<Exam>>
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package io.github.wulkanowy.sdk.hebe
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
|
||||
@Ignore
|
||||
class HebeRemoteTest {
|
||||
|
||||
private val hebe = Hebe()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
with(hebe) {
|
||||
logLevel = HttpLoggingInterceptor.Level.BODY
|
||||
keyId = "///"
|
||||
privatePem = "///"
|
||||
baseUrl = "https://api.fakelog.cf/powiatwulkanowy/"
|
||||
pupilId = 1234
|
||||
schoolId = "008520"
|
||||
deviceModel = "Pixel 4a (5G)"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `register device`() = runTest {
|
||||
val res = hebe.register(
|
||||
firebaseToken = "",
|
||||
token = "FK11234",
|
||||
pin = "123456",
|
||||
symbol = "powiatwulkanowy",
|
||||
)
|
||||
assertTrue(res.privatePem.isNotEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get students`() = runTest {
|
||||
val res = hebe.getStudents(hebe.baseUrl)
|
||||
assertTrue(res.isNotEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get grades`() = runTest {
|
||||
val grades = hebe.getGrades(560)
|
||||
assertTrue(grades.isNotEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get grades summary`() = runTest {
|
||||
val summaries = hebe.getGradesSummary(560)
|
||||
assertTrue(summaries.isNotEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get exams`() = runTest {
|
||||
val exams = hebe.getExams(LocalDate.of(2023, 4, 1), LocalDate.of(2023, 5, 1))
|
||||
assertTrue(exams.isNotEmpty())
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.kotlin.jvm'
|
||||
id 'kotlin-kapt'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:uonet-request-signer:36c4365"
|
||||
|
||||
implementation "com.brsanthu:migbase64:2.2"
|
||||
|
||||
implementation "com.squareup.retrofit2:retrofit:$retrofit"
|
||||
implementation "com.squareup.retrofit2:converter-moshi:$retrofit"
|
||||
implementation "com.squareup.retrofit2:converter-scalars:$retrofit"
|
||||
|
||||
implementation "com.squareup.moshi:moshi:1.11.0"
|
||||
implementation 'com.squareup.moshi:moshi-adapters:1.11.0'
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.11.0"
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import java.time.LocalDateTime.now
|
||||
import java.time.ZoneOffset
|
||||
import java.util.UUID
|
||||
|
||||
@Suppress("unused")
|
||||
@JsonClass(generateAdapter = true)
|
||||
open class ApiRequest(
|
||||
|
||||
@Json(name = "RemoteMobileTimeKey")
|
||||
val remoteMobileTimeKey: Long = now().toEpochSecond(ZoneOffset.UTC),
|
||||
|
||||
@Json(name = "TimeKey")
|
||||
val timeKey: Long = now().toEpochSecond(ZoneOffset.UTC) - 1,
|
||||
|
||||
@Json(name = "RequestId")
|
||||
val requestId: String = UUID.randomUUID().toString(),
|
||||
|
||||
@Json(name = "RemoteMobileAppVersion")
|
||||
val remoteMobileAppVersion: String = MOBILE_APP_VERSION,
|
||||
|
||||
@Json(name = "RemoteMobileAppName")
|
||||
val remoteMobileAppName: String = "VULCAN-Android-ModulUcznia"
|
||||
) {
|
||||
companion object {
|
||||
const val MOBILE_APP_VERSION = "20.1.1.447"
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ApiResponse<out T>(
|
||||
|
||||
@Json(name = "Status")
|
||||
val status: String,
|
||||
|
||||
@Json(name = "TimeKey")
|
||||
val timeKey: String,
|
||||
|
||||
@Json(name = "TimeValue")
|
||||
val timeValue: String,
|
||||
|
||||
@Json(name = "RequestId")
|
||||
val requestId: String,
|
||||
|
||||
@Json(name = "DayOfWeek")
|
||||
val dayOfWeek: String,
|
||||
|
||||
@Json(name = "AppVersion")
|
||||
val appVersion: String,
|
||||
|
||||
@Json(name = "Data")
|
||||
val data: T?
|
||||
)
|
|
@ -1,186 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile
|
||||
|
||||
import com.migcomponents.migbase64.Base64
|
||||
import io.github.wulkanowy.sdk.mobile.attendance.Attendance
|
||||
import io.github.wulkanowy.sdk.mobile.dictionaries.Dictionaries
|
||||
import io.github.wulkanowy.sdk.mobile.exams.Exam
|
||||
import io.github.wulkanowy.sdk.mobile.exception.InvalidPinException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.NoStudentsException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.TokenDeadException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.TokenNotFoundException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.UnknownTokenException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.UnsupportedTokenException
|
||||
import io.github.wulkanowy.sdk.mobile.grades.Grade
|
||||
import io.github.wulkanowy.sdk.mobile.grades.GradesSummaryResponse
|
||||
import io.github.wulkanowy.sdk.mobile.homework.Homework
|
||||
import io.github.wulkanowy.sdk.mobile.messages.Message
|
||||
import io.github.wulkanowy.sdk.mobile.messages.Recipient
|
||||
import io.github.wulkanowy.sdk.mobile.notes.Note
|
||||
import io.github.wulkanowy.sdk.mobile.register.CertificateResponse
|
||||
import io.github.wulkanowy.sdk.mobile.register.Student
|
||||
import io.github.wulkanowy.sdk.mobile.repository.RepositoryManager
|
||||
import io.github.wulkanowy.sdk.mobile.school.Teacher
|
||||
import io.github.wulkanowy.sdk.mobile.timetable.Lesson
|
||||
import io.github.wulkanowy.signer.getPrivateKeyFromCert
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import java.nio.charset.Charset
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class Mobile {
|
||||
|
||||
var classId = 0
|
||||
|
||||
var studentId = 0
|
||||
|
||||
var loginId = 0
|
||||
|
||||
private val resettableManager = resettableManager()
|
||||
|
||||
var logLevel = HttpLoggingInterceptor.Level.BASIC
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var privateKey = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var certKey = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var baseUrl = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
var schoolSymbol = ""
|
||||
set(value) {
|
||||
field = value
|
||||
resettableManager.reset()
|
||||
}
|
||||
|
||||
private val serviceManager by resettableLazy(resettableManager) { RepositoryManager(logLevel, privateKey, certKey, interceptors, baseUrl, schoolSymbol) }
|
||||
|
||||
private val routes by resettableLazy(resettableManager) { serviceManager.getRoutesRepository() }
|
||||
|
||||
private val mobile by resettableLazy(resettableManager) { serviceManager.getMobileRepository() }
|
||||
|
||||
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf()
|
||||
|
||||
fun setInterceptor(interceptor: Interceptor, network: Boolean = false) {
|
||||
interceptors.add(interceptor to network)
|
||||
}
|
||||
|
||||
private lateinit var dictionaries: Dictionaries
|
||||
|
||||
suspend fun getDictionaries(): Dictionaries {
|
||||
if (::dictionaries.isInitialized) return dictionaries
|
||||
|
||||
return mobile.getDictionaries(0, 0, classId)
|
||||
.apply { dictionaries = this }
|
||||
}
|
||||
|
||||
suspend fun getCertificate(token: String, pin: String, symbol: String, deviceName: String, androidVer: String, firebaseToken: String): CertificateResponse {
|
||||
val baseUrl = routes.getRouteByToken(token)
|
||||
return serviceManager.getRegisterRepository(baseUrl, symbol).getCertificate(token, pin, deviceName, androidVer, firebaseToken)
|
||||
}
|
||||
|
||||
suspend fun getStudents(certRes: CertificateResponse, apiKey: String = ""): List<Student> {
|
||||
if (certRes.isError) when {
|
||||
certRes.message == "TokenDead" -> throw TokenDeadException(certRes.message)
|
||||
certRes.message == "TokenNotFound" -> throw TokenNotFoundException(certRes.message)
|
||||
certRes.message?.startsWith("Podany numer PIN jest niepoprawny") == true -> throw InvalidPinException(certRes.message.orEmpty())
|
||||
certRes.message?.startsWith("Trzykrotnie wpisano niepoprawny kod PIN") == true -> throw InvalidPinException(certRes.message.orEmpty())
|
||||
certRes.message == "NoPupils" -> throw NoStudentsException(certRes.message.orEmpty())
|
||||
certRes.message == "OnlyKindergarten" -> throw UnsupportedTokenException(certRes.message)
|
||||
else -> throw UnknownTokenException(certRes.message.orEmpty())
|
||||
}
|
||||
|
||||
val cert = certRes.tokenCert!!
|
||||
certKey = cert.certificateKey
|
||||
baseUrl = cert.baseUrl.removeSuffix("/")
|
||||
privateKey = getPrivateKeyFromCert(apiKey.ifEmpty {
|
||||
Base64.decode(if (cert.baseUrl.contains("fakelog")) "KDAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OUFCKQ==" else "KENFNzVFQTU5OEM3NzQzQUQ5QjBCNzMyOERFRDg1QjA2KQ==")
|
||||
.toString(Charset.defaultCharset())
|
||||
.removeSurrounding("(", ")")
|
||||
}, cert.certificatePfx)
|
||||
|
||||
return serviceManager.getRegisterRepository(cert.baseUrl).getStudents().map {
|
||||
it.copy().apply {
|
||||
certificateKey = this@Mobile.certKey
|
||||
privateKey = this@Mobile.privateKey
|
||||
mobileBaseUrl = this@Mobile.baseUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getStudents(): List<Student> {
|
||||
return serviceManager.getRegisterRepository(baseUrl).getStudents()
|
||||
}
|
||||
|
||||
suspend fun getAttendance(start: LocalDate, end: LocalDate, classificationPeriodId: Int): List<Attendance> {
|
||||
return mobile.getAttendance(start, end, classId, classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getExams(start: LocalDate, end: LocalDate, classificationPeriodId: Int): List<Exam> {
|
||||
return mobile.getExams(start, end, classId, classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getGrades(classificationPeriodId: Int): Pair<List<Grade>, GradesSummaryResponse> {
|
||||
return getGradesDetails(classificationPeriodId) to getGradesSummary(classificationPeriodId)
|
||||
}
|
||||
|
||||
suspend fun getGradesDetails(classificationPeriodId: Int): List<Grade> {
|
||||
return mobile.getGradesDetails(classId, classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getGradesSummary(classificationPeriodId: Int): GradesSummaryResponse {
|
||||
return mobile.getGradesSummary(classId, classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getHomework(start: LocalDate, end: LocalDate, classificationPeriodId: Int): List<Homework> {
|
||||
return mobile.getHomework(start, end, classId, classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getNotes(classificationPeriodId: Int): List<Note> {
|
||||
return mobile.getNotes(classificationPeriodId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getTeachers(studentId: Int, semesterId: Int): List<Teacher> {
|
||||
return mobile.getTeachers(studentId, semesterId)
|
||||
}
|
||||
|
||||
suspend fun getMessages(start: LocalDateTime, end: LocalDateTime): List<Message> {
|
||||
return mobile.getMessages(start, end, loginId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getMessagesSent(start: LocalDateTime, end: LocalDateTime): List<Message> {
|
||||
return mobile.getMessagesSent(start, end, loginId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getMessagesDeleted(start: LocalDateTime, end: LocalDateTime): List<Message> {
|
||||
return mobile.getMessagesDeleted(start, end, loginId, studentId)
|
||||
}
|
||||
|
||||
suspend fun changeMessageStatus(messageId: Int, folder: String, status: String): String {
|
||||
return mobile.changeMessageStatus(messageId, folder, status, loginId, studentId)
|
||||
}
|
||||
|
||||
suspend fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Message {
|
||||
val sender = getStudents().singleOrNull { it.loginId == loginId }?.name.orEmpty()
|
||||
return mobile.sendMessage(sender, subject, content, recipients, loginId, studentId)
|
||||
}
|
||||
|
||||
suspend fun getTimetable(start: LocalDate, end: LocalDate, classificationPeriodId: Int): List<Lesson> {
|
||||
return mobile.getTimetable(start, end, classId, classificationPeriodId, studentId)
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter.ofPattern
|
||||
|
||||
fun LocalDate.toFormat(): String = format(ofPattern("yyyy-MM-dd"))
|
||||
|
||||
fun LocalDateTime.toFormat(): String = format(ofPattern("yyyy-MM-dd"))
|
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.attendance
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Attendance(
|
||||
|
||||
@Json(name = "IdKategoria")
|
||||
val categoryId: Int,
|
||||
|
||||
@Json(name = "Numer")
|
||||
val number: Int,
|
||||
|
||||
@Json(name = "IdPoraLekcji")
|
||||
val lessonTimeId: Int,
|
||||
|
||||
@Json(name = "Dzien")
|
||||
val date: Long,
|
||||
|
||||
@Json(name = "DzienTekst")
|
||||
val dateText: String,
|
||||
|
||||
@Json(name = "IdPrzedmiot")
|
||||
val subjectId: Int,
|
||||
|
||||
@Json(name = "PrzedmiotNazwa")
|
||||
val subjectName: String
|
||||
)
|
|
@ -1,24 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.attendance
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AttendanceRequest(
|
||||
|
||||
@Json(name = "DataPoczatkowa")
|
||||
val startDate: String,
|
||||
|
||||
@Json(name = "DataKoncowa")
|
||||
val endDate: String,
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int,
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,23 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.attendance
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AttendanceResponse(
|
||||
|
||||
@Json(name = "DataPoczatkowa")
|
||||
val dateStart: Long,
|
||||
|
||||
@Json(name = "DataPoczatkowaTekst")
|
||||
val dateStartText: String,
|
||||
|
||||
@Json(name = "DataKoncowa")
|
||||
val dateEnd: Long,
|
||||
|
||||
@Json(name = "DataKoncowaTekst")
|
||||
val dateEndText: String,
|
||||
|
||||
@Json(name = "Frekwencje")
|
||||
val items: List<Attendance>
|
||||
)
|
|
@ -1,35 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AttendanceCategory(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Pozycja")
|
||||
val position: Int,
|
||||
|
||||
@Json(name = "Obecnosc")
|
||||
val presence: Boolean,
|
||||
|
||||
@Json(name = "Nieobecnosc")
|
||||
val absence: Boolean,
|
||||
|
||||
@Json(name = "Zwolnienie")
|
||||
val exemption: Boolean,
|
||||
|
||||
@Json(name = "Spoznienie")
|
||||
val lateness: Boolean,
|
||||
|
||||
@Json(name = "Usprawiedliwione")
|
||||
val excused: Boolean,
|
||||
|
||||
@Json(name = "Usuniete")
|
||||
val deleted: Boolean
|
||||
)
|
|
@ -1,26 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AttendanceType(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Symbol")
|
||||
val symbol: String,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Aktywny")
|
||||
val active: Boolean,
|
||||
|
||||
@Json(name = "WpisDomyslny")
|
||||
val defaultEntry: Boolean,
|
||||
|
||||
@Json(name = "IdKategoriaFrek")
|
||||
val categoryId: Int
|
||||
)
|
|
@ -1,35 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Dictionaries(
|
||||
|
||||
@Json(name = "TimeKey")
|
||||
val timeKey: Long,
|
||||
|
||||
@Json(name = "Nauczyciele")
|
||||
val teachers: List<Teacher>,
|
||||
|
||||
@Json(name = "Pracownicy")
|
||||
val employees: List<Employee>,
|
||||
|
||||
@Json(name = "Przedmioty")
|
||||
val subjects: List<Subject>,
|
||||
|
||||
@Json(name = "PoryLekcji")
|
||||
val lessonTimes: List<LessonTime>,
|
||||
|
||||
@Json(name = "KategorieOcen")
|
||||
val gradeCategories: List<GradeCategory>,
|
||||
|
||||
@Json(name = "KategorieUwag")
|
||||
val noteCategories: List<NoteCategory>,
|
||||
|
||||
@Json(name = "KategorieFrekwencji")
|
||||
val attendanceCategories: List<AttendanceCategory>,
|
||||
|
||||
@Json(name = "TypyFrekwencji")
|
||||
val attendanceTypes: List<AttendanceType>
|
||||
)
|
|
@ -1,19 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DictionariesRequest(
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val userId: Int,
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int
|
||||
|
||||
) : ApiRequest()
|
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Employee(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Imie")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Nazwisko")
|
||||
val surname: String,
|
||||
|
||||
@Json(name = "Kod")
|
||||
val code: String,
|
||||
|
||||
@Json(name = "Aktywny")
|
||||
val active: Boolean,
|
||||
|
||||
@Json(name = "Nauczyciel")
|
||||
val teacher: Boolean,
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int
|
||||
)
|
|
@ -1,17 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GradeCategory(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Kod")
|
||||
val code: String,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String
|
||||
)
|
|
@ -1,26 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class LessonTime(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Numer")
|
||||
val number: Int,
|
||||
|
||||
@Json(name = "Poczatek")
|
||||
val start: Long,
|
||||
|
||||
@Json(name = "PoczatekTekst")
|
||||
val startText: String,
|
||||
|
||||
@Json(name = "Koniec")
|
||||
val end: Long,
|
||||
|
||||
@Json(name = "KoniecTekst")
|
||||
val endText: String
|
||||
)
|
|
@ -1,17 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class NoteCategory(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Aktywny")
|
||||
val isActive: Boolean
|
||||
)
|
|
@ -1,23 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Subject(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Kod")
|
||||
val code: String,
|
||||
|
||||
@Json(name = "Aktywny")
|
||||
val active: Boolean,
|
||||
|
||||
@Json(name = "Pozycja")
|
||||
val position: Int
|
||||
)
|
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.dictionaries
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Teacher(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Imie")
|
||||
val name: String,
|
||||
|
||||
@Json(name = "Nazwisko")
|
||||
val surname: String,
|
||||
|
||||
@Json(name = "Kod")
|
||||
val code: String,
|
||||
|
||||
@Json(name = "Aktywny")
|
||||
val active: Boolean,
|
||||
|
||||
@Json(name = "Nauczyciel")
|
||||
val teacher: Boolean,
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int
|
||||
)
|
|
@ -1,41 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exams
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Exam(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "IdPrzedmiot")
|
||||
val subjectId: Int,
|
||||
|
||||
@Json(name = "IdPracownik")
|
||||
val employeeId: Int,
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int?,
|
||||
|
||||
@Json(name = "IdPodzial")
|
||||
val divideId: Int?,
|
||||
|
||||
@Json(name = "PodzialNazwa")
|
||||
val divideName: String?,
|
||||
|
||||
@Json(name = "Rodzaj")
|
||||
val type: Boolean, // false - quiz, true - test
|
||||
|
||||
@Json(name = "RodzajNumer")
|
||||
val typeNumber: Int,
|
||||
|
||||
@Json(name = "Opis")
|
||||
val description: String,
|
||||
|
||||
@Json(name = "Data")
|
||||
val date: Long,
|
||||
|
||||
@Json(name = "DataTekst")
|
||||
val dateText: String
|
||||
)
|
|
@ -1,24 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exams
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ExamsRequest(
|
||||
|
||||
@Json(name = "DataPoczatkowa")
|
||||
val startDate: String,
|
||||
|
||||
@Json(name = "DataKoncowa")
|
||||
val endDate: String,
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int,
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,5 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class InvalidPinException(message: String) : IOException(message)
|
|
@ -1,5 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
open class InvalidTokenException internal constructor(message: String) : IOException(message)
|
|
@ -1,5 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class NoStudentsException(message: String) : IOException(message)
|
|
@ -1,3 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
class TokenDeadException(message: String) : InvalidTokenException(message)
|
|
@ -1,3 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
class TokenNotFoundException(message: String) : InvalidTokenException(message)
|
|
@ -1,3 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
class UnknownTokenException(message: String) : InvalidTokenException(message)
|
|
@ -1,5 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class UnsupportedTokenException(message: String) : IOException(message)
|
|
@ -1,68 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.grades
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Grade(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "Pozycja")
|
||||
val position: Int,
|
||||
|
||||
@Json(name = "PrzedmiotPozycja")
|
||||
val subjectPosition: Int,
|
||||
|
||||
@Json(name = "IdPrzedmiot")
|
||||
val subjectId: Int,
|
||||
|
||||
@Json(name = "IdKategoria")
|
||||
val categoryId: Int,
|
||||
|
||||
@Json(name = "Wpis")
|
||||
val entry: String,
|
||||
|
||||
@Json(name = "Wartosc")
|
||||
val value: Double,
|
||||
|
||||
@Json(name = "WagaModyfikatora")
|
||||
val modificationWeight: Double?,
|
||||
|
||||
@Json(name = "WagaOceny")
|
||||
val gradeWeight: Double,
|
||||
|
||||
@Json(name = "Licznik")
|
||||
val counter: Double?,
|
||||
|
||||
@Json(name = "Mianownik")
|
||||
val denominator: Int?,
|
||||
|
||||
@Json(name = "Komentarz")
|
||||
val comment: String?,
|
||||
|
||||
@Json(name = "Waga")
|
||||
val weight: String,
|
||||
|
||||
@Json(name = "Opis")
|
||||
val description: String,
|
||||
|
||||
@Json(name = "DataUtworzenia")
|
||||
val creationDate: Long,
|
||||
|
||||
@Json(name = "DataUtworzeniaTekst")
|
||||
val creationDateText: String,
|
||||
|
||||
@Json(name = "DataModyfikacji")
|
||||
val modificationDate: Long,
|
||||
|
||||
@Json(name = "DataModyfikacjiTekst")
|
||||
val modificationDateText: String,
|
||||
|
||||
@Json(name = "IdPracownikD")
|
||||
val employeeIdD: Int,
|
||||
|
||||
@Json(name = "IdPracownikM")
|
||||
val employeeIdM: Int
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.grades
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GradeSummary(
|
||||
|
||||
@Json(name = "IdPrzedmiot")
|
||||
val subjectId: Int = 0,
|
||||
|
||||
@Json(name = "Wpis")
|
||||
val entry: String = "",
|
||||
|
||||
@Json(name = "SredniaOcen")
|
||||
val average: String = "0",
|
||||
|
||||
@Json(name = "SumaPunktow")
|
||||
val pointsSum: String = ""
|
||||
)
|
|
@ -1,18 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.grades
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GradesRequest(
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int,
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,17 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.grades
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GradesSummaryResponse(
|
||||
|
||||
@Json(name = "OcenyPrzewidywane")
|
||||
val predicted: List<GradeSummary>,
|
||||
|
||||
@Json(name = "OcenyKlasyfikacyjne")
|
||||
val evaluative: List<GradeSummary>,
|
||||
|
||||
@Json(name = "SrednieOcen")
|
||||
val average: List<GradeSummary>
|
||||
)
|
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.homework
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Homework(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int,
|
||||
|
||||
@Json(name = "Data")
|
||||
val date: Long,
|
||||
|
||||
@Json(name = "DataTekst")
|
||||
val dateText: String,
|
||||
|
||||
@Json(name = "IdPracownik")
|
||||
val employeeId: Int,
|
||||
|
||||
@Json(name = "IdPrzedmiot")
|
||||
val subjectId: Int,
|
||||
|
||||
@Json(name = "Opis")
|
||||
val content: String
|
||||
)
|
|
@ -1,24 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.homework
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class HomeworkRequest(
|
||||
|
||||
@Json(name = "DataPoczatkowa")
|
||||
val startDate: String,
|
||||
|
||||
@Json(name = "DataKoncowa")
|
||||
val endDate: String,
|
||||
|
||||
@Json(name = "IdOddzial")
|
||||
val classId: Int,
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,21 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.interceptor
|
||||
|
||||
import io.github.wulkanowy.sdk.mobile.exception.InvalidSymbolException
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
|
||||
class ErrorInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val response = chain.proceed(chain.request())
|
||||
val body = response.peekBody(Long.MAX_VALUE).string()
|
||||
|
||||
when {
|
||||
body == "Bad Request" -> throw IOException(body)
|
||||
body.contains("Podany symbol grupujący jest nieprawidłowy") -> throw InvalidSymbolException()
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.interceptor
|
||||
|
||||
import io.github.wulkanowy.signer.signContent
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okio.Buffer
|
||||
import java.nio.charset.Charset
|
||||
|
||||
class SignInterceptor(
|
||||
private val privateKey: String,
|
||||
private val certKey: String
|
||||
) : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val original = chain.request()
|
||||
val request = original.newBuilder()
|
||||
|
||||
request.header("User-Agent", "MobileUserAgent")
|
||||
|
||||
if (privateKey.isNotBlank()) {
|
||||
val signature = Buffer().run {
|
||||
original.body()?.writeTo(this)
|
||||
signContent(privateKey, readString(Charset.defaultCharset()))
|
||||
}
|
||||
|
||||
request.header("RequestCertificateKey", certKey)
|
||||
request.header("RequestSignatureValue", signature)
|
||||
}
|
||||
|
||||
return chain.proceed(request.method(original.method(), original.body()).build())
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.messages
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Message(
|
||||
|
||||
@Json(name = "WiadomoscId")
|
||||
val messageId: Int,
|
||||
|
||||
@Json(name = "Nadawca")
|
||||
val senderName: String?,
|
||||
|
||||
@Json(name = "NadawcaId")
|
||||
val senderId: Int,
|
||||
|
||||
@Json(name = "Adresaci")
|
||||
val recipients: List<Recipient>?,
|
||||
|
||||
@Json(name = "Tytul")
|
||||
val subject: String,
|
||||
|
||||
@Json(name = "Tresc")
|
||||
val content: String,
|
||||
|
||||
@Json(name = "DataWyslania")
|
||||
val sentDate: String,
|
||||
|
||||
@Json(name = "DataWyslaniaUnixEpoch")
|
||||
val sentDateTime: Long,
|
||||
|
||||
@Json(name = "GodzinaWyslania")
|
||||
val sentHour: String,
|
||||
|
||||
@Json(name = "DataPrzeczytania")
|
||||
val readDate: String?,
|
||||
|
||||
@Json(name = "DataPrzeczytaniaUnixEpoch")
|
||||
val readDateTime: Long?,
|
||||
|
||||
@Json(name = "GodzinaPrzeczytania")
|
||||
val readHour: String?,
|
||||
|
||||
@Json(name = "StatusWiadomosci")
|
||||
val status: String,
|
||||
|
||||
@Json(name = "FolderWiadomosci")
|
||||
val folder: String,
|
||||
|
||||
@Json(name = "Nieprzeczytane")
|
||||
val unread: String?,
|
||||
|
||||
@Json(name = "Przeczytane")
|
||||
val read: String?
|
||||
)
|
|
@ -1,24 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.messages
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageStatusChangeRequest(
|
||||
|
||||
@Json(name = "WiadomoscId")
|
||||
val messageId: Int,
|
||||
|
||||
@Json(name = "FolderWiadomosci")
|
||||
val folder: String,
|
||||
|
||||
@Json(name = "Status")
|
||||
val status: String,
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,21 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.messages
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessagesRequest(
|
||||
|
||||
@Json(name = "DataPoczatkowa")
|
||||
val startDate: String,
|
||||
|
||||
@Json(name = "DataKoncowa")
|
||||
val endDate: String,
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,14 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.messages
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Recipient(
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@Json(name = "Nazwa")
|
||||
val name: String
|
||||
)
|
|
@ -1,26 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.messages
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class SendMessageRequest(
|
||||
|
||||
@Json(name = "NadawcaWiadomosci")
|
||||
val sender: String,
|
||||
|
||||
@Json(name = "Tytul")
|
||||
val subject: String,
|
||||
|
||||
@Json(name = "Tresc")
|
||||
val content: String,
|
||||
|
||||
@Json(name = "Adresaci")
|
||||
val recipients: List<Recipient>,
|
||||
|
||||
@Json(name = "LoginId")
|
||||
val loginId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
)
|
|
@ -1,50 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.notes
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Note(
|
||||
|
||||
@Json(name = "Id")
|
||||
val id: Int,
|
||||
|
||||
@Json(name = "IdKategoriaUwag")
|
||||
val noteCategoryId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int,
|
||||
|
||||
@Json(name = "UczenImie")
|
||||
val studentName: String,
|
||||
|
||||
@Json(name = "UczenNazwisko")
|
||||
val studentSurname: String,
|
||||
|
||||
@Json(name = "IdPracownik")
|
||||
val employeeId: Int,
|
||||
|
||||
@Json(name = "PracownikImie")
|
||||
val employeeName: String,
|
||||
|
||||
@Json(name = "PracownikNazwisko")
|
||||
val employeeSurname: String,
|
||||
|
||||
@Json(name = "DataWpisu")
|
||||
val entryDate: Long,
|
||||
|
||||
@Json(name = "DataWpisuTekst")
|
||||
val entryDateText: String,
|
||||
|
||||
@Json(name = "DataModyfikacji")
|
||||
val modificationDate: Long?,
|
||||
|
||||
@Json(name = "DataModyfikacjiTekst")
|
||||
val modificationDateText: String?,
|
||||
|
||||
@Json(name = "UwagaKey")
|
||||
val noteKey: String,
|
||||
|
||||
@Json(name = "TrescUwagi")
|
||||
val content: String
|
||||
)
|
|
@ -1,15 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.notes
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class NotesRequest(
|
||||
|
||||
@Json(name = "IdOkresKlasyfikacyjny")
|
||||
val classificationPeriodId: Int,
|
||||
|
||||
@Json(name = "IdUczen")
|
||||
val studentId: Int
|
||||
) : ApiRequest()
|
|
@ -1,41 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.register
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import io.github.wulkanowy.sdk.mobile.ApiRequest
|
||||
import java.util.UUID
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CertificateRequest(
|
||||
|
||||
@Json(name = "PIN")
|
||||
val pin: String,
|
||||
|
||||
@Json(name = "TokenKey")
|
||||
val tokenKey: String,
|
||||
|
||||
@Json(name = "AppVersion")
|
||||
val appVersion: String = MOBILE_APP_VERSION,
|
||||
|
||||
@Json(name = "DeviceId")
|
||||
val deviceId: String = UUID.randomUUID().toString(),
|
||||
|
||||
@Json(name = "DeviceName")
|
||||
val deviceName: String,
|
||||
|
||||
@Json(name = "DeviceNameUser")
|
||||
val deviceNameUser: String = "",
|
||||
|
||||
@Json(name = "DeviceDescription")
|
||||
val deviceDescription: String = "",
|
||||
|
||||
@Json(name = "DeviceSystemType")
|
||||
val deviceSystemType: String = "Android",
|
||||
|
||||
@Json(name = "DeviceSystemVersion")
|
||||
val deviceSystemVersion: String = "8.1.0",
|
||||
|
||||
@Json(name = "FirebaseTokenKey")
|
||||
val firebaseToken: String
|
||||
|
||||
) : ApiRequest()
|
|
@ -1,26 +0,0 @@
|
|||
package io.github.wulkanowy.sdk.mobile.register
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CertificateResponse(
|
||||
|
||||
@Json(name = "IsError")
|
||||
val isError: Boolean,
|
||||
|
||||
@Json(name = "IsMessageForUser")
|
||||
val isMessageForUser: Boolean,
|
||||
|
||||
@Json(name = "Message")
|
||||
val message: String?,
|
||||
|
||||
@Json(name = "TokenKey")
|
||||
val tokenKey: String?,
|
||||
|
||||
@Json(name = "TokenStatus")
|
||||
val tokenStatus: String?,
|
||||
|
||||
@Json(name = "TokenCert")
|
||||
val tokenCert: TokenCert?
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue