mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-16 15:31:54 +02:00
Compare commits
443 Commits
v4.0-beta.
...
v4.6-beta.
Author | SHA1 | Date | |
---|---|---|---|
359432d24d | |||
edf8ec20f0 | |||
3ad9e5da1f | |||
459bbf78b2 | |||
d0baf02750 | |||
a5bb7d9c6e | |||
a939d95ea3 | |||
4c081c970e | |||
b75ab76c2a | |||
9da6dbccb3 | |||
66444ae35b | |||
3e8b3de2b7 | |||
85ac5769a1 | |||
93e3d5994a | |||
0cf24c527b | |||
97c5acd6ba | |||
30aeb70647 | |||
b599d679c4 | |||
1eecd24d91 | |||
c698dfdb73 | |||
c7a44f5ced | |||
c8ee6ff1e7 | |||
552acd4043 | |||
ede101ea20 | |||
13c2640ed5 | |||
dd0739fd4b | |||
9023f13932 | |||
f8456fb087 | |||
9b48041cd9 | |||
46cecf3474 | |||
c27254bcad | |||
80333cdea4 | |||
6aee3ea420 | |||
a11a44b768 | |||
e869107101 | |||
5903bbe59d | |||
6c0ddd3e6d | |||
621a7ac642 | |||
e86b47fb1b | |||
98fb7ac8c9 | |||
f49e39e858 | |||
8fc57cd3f5 | |||
a9eda087e0 | |||
3f36a284ee | |||
1814fd67e1 | |||
54e49af943 | |||
d6a67a0da6 | |||
28725c6400 | |||
4fc965d970 | |||
2aaf713d58 | |||
c7d2ac4e3e | |||
ae20c30c88 | |||
aef3f66654 | |||
c7abde8f11 | |||
2fcff33bd6 | |||
b08e4c2d3d | |||
73ff09052c | |||
9649afd43f | |||
ed3a245b51 | |||
477730708f | |||
f39d0c595d | |||
46407f9647 | |||
6ecb97b87e | |||
ecdaaeae65 | |||
a0c302b663 | |||
b31039ecd9 | |||
5c84086f42 | |||
752cdfa8d6 | |||
8e3d404352 | |||
810cfd8092 | |||
bd2a9524c6 | |||
d780d5118d | |||
f1570b8eb9 | |||
de0f29a09e | |||
c0d11c91e3 | |||
22c540a3d4 | |||
b7e35d0322 | |||
7bcd6bf038 | |||
ea4591144b | |||
7627d184a2 | |||
076b485fda | |||
09cb97e367 | |||
4e1f2ed41a | |||
281b6a95ef | |||
e40871c0d0 | |||
b74eeed994 | |||
ccde482364 | |||
a02033d0f3 | |||
6c6bc89f57 | |||
1e3da45340 | |||
0d366adddb | |||
2c24eba46d | |||
7c6dbca986 | |||
33a8fa2a1e | |||
300e2c4bc2 | |||
f883318bd2 | |||
5460c1e2a0 | |||
137c975e81 | |||
001de4a88c | |||
5dcb3fd580 | |||
f13995aa5c | |||
e23deb5ca6 | |||
d688b379a2 | |||
d6a796e25e | |||
e02d3e571d | |||
907b75b22d | |||
c3660b5f80 | |||
7ff10df70c | |||
83e1b21ec3 | |||
deb54e4b24 | |||
48873caecc | |||
cadd1a3dbd | |||
f09f069b2c | |||
1fb5aaed5d | |||
65ba330d5f | |||
795317f13f | |||
031cc05209 | |||
0ac8e1d9c1 | |||
4389dc9d79 | |||
b13257cb78 | |||
fcffa2afeb | |||
3c2f85f263 | |||
0a2323acf3 | |||
45c2948ed1 | |||
f72a6103b5 | |||
9261848369 | |||
7f4e45c57c | |||
180154b684 | |||
a4f58eb19b | |||
fada483d55 | |||
3ae9ba3d61 | |||
15102fe818 | |||
8864bb2a5e | |||
ef1cdd5b20 | |||
35f4f34342 | |||
1a8134459a | |||
a6ce3a5068 | |||
328b20f78b | |||
771712da99 | |||
65e0e10db6 | |||
62e0e53354 | |||
a5461a488a | |||
192dd0c4c7 | |||
c49755c0eb | |||
c8c758958d | |||
e068f1944f | |||
97412a3736 | |||
9167d53a1a | |||
6436a17036 | |||
5ab5dbe940 | |||
d68ab0d010 | |||
f70a1f5730 | |||
85106a01d7 | |||
90e99e241a | |||
3f61ab8299 | |||
f685a4dceb | |||
e8dad29e5d | |||
13a3f66db3 | |||
dc9e6081c5 | |||
26f8c03570 | |||
97e0f36f09 | |||
27e49b10fd | |||
97dc8d12f1 | |||
9b13552b73 | |||
d8559637a5 | |||
00a90a14dc | |||
d56afb034b | |||
0327ba37f1 | |||
12a54e58b5 | |||
238250e8c9 | |||
041bfc6cc0 | |||
8a4866cb62 | |||
0e4d609bbf | |||
f07b12bd87 | |||
0413dbffa2 | |||
c214b48409 | |||
91a6366548 | |||
03c9932b8c | |||
ea4919a25d | |||
f98b174857 | |||
c0aeb0d2f3 | |||
fcb627aac6 | |||
7f0aea29cd | |||
f6dcbb6594 | |||
b790421693 | |||
f5a7799924 | |||
b052b5bd66 | |||
12d8de1def | |||
9303483470 | |||
f8adc86a0e | |||
db57c258c5 | |||
ddb2760c16 | |||
14d267a95a | |||
a6c4053896 | |||
949a68ec1d | |||
93333a8c48 | |||
da48c059ec | |||
ee5566d1ef | |||
b794b30346 | |||
0db6393bb0 | |||
fcc3c55110 | |||
328c07eaf4 | |||
b004ec048e | |||
b9f83875a0 | |||
8c869d082b | |||
043f8210ba | |||
41a79caf83 | |||
0427fa6087 | |||
2f3c912dbe | |||
219a7443c0 | |||
6deb408d80 | |||
c6e1ff2164 | |||
bc0918a115 | |||
55ff9173be | |||
d4d548846f | |||
ef4527f140 | |||
0b1e7242bb | |||
30b6ac2a06 | |||
a7fa7cb5e4 | |||
f3e87f9016 | |||
a983af6c28 | |||
114c841f0c | |||
e271048577 | |||
b8c5925e82 | |||
9bda6c8869 | |||
d1608d308c | |||
b8e1e1d33a | |||
8099a037e7 | |||
af23c932a6 | |||
4edabbb186 | |||
37a5bea79b | |||
40cdc7d713 | |||
49825aca48 | |||
1d57c4e705 | |||
87ae5787ee | |||
20f16c25a3 | |||
6f1ec79d9b | |||
18c7eea89c | |||
f73060aeb6 | |||
2f653b83b6 | |||
445dec907d | |||
927316d24b | |||
3957453ed6 | |||
0296c704cb | |||
1e7fe972de | |||
c95bc656ea | |||
a082d95b04 | |||
6866dd4801 | |||
2186da416e | |||
22d859fcde | |||
39514b69b3 | |||
c384736840 | |||
507657f273 | |||
60641742ed | |||
0fc6f07986 | |||
1b2bdc0580 | |||
9bac239f77 | |||
371acb2d2a | |||
454f82e139 | |||
e8da249353 | |||
c7950c53da | |||
b5502478e4 | |||
4480a7e486 | |||
7c7dff743b | |||
c568cd3f2e | |||
6ec2bc6f21 | |||
af3b6f3a97 | |||
d855118610 | |||
c9992d9fe8 | |||
85fe2636cc | |||
35f4a31a76 | |||
1e494ebb70 | |||
ed93627505 | |||
b9b4b0036f | |||
4aa31424d6 | |||
8a825227cb | |||
cc1b581d7e | |||
9936d90ae2 | |||
df1a241b2b | |||
ae89b33fb7 | |||
e05b483f5c | |||
715f536b23 | |||
930813fb8a | |||
acd5e9b998 | |||
06011bf4ae | |||
30e15b813c | |||
fcd7a7f349 | |||
42ef40439e | |||
098beb14fe | |||
0b186a754a | |||
d00963b53d | |||
e282af0e80 | |||
630361849c | |||
88a1de50ca | |||
d8263d0b6a | |||
611ab0f100 | |||
70c307b796 | |||
054a233ad6 | |||
55268f1c43 | |||
1bec6d281c | |||
f17a02be54 | |||
4e8fdd2225 | |||
59819b4a96 | |||
673378d8d9 | |||
30044d6b21 | |||
ee43d40680 | |||
1354faf8c7 | |||
1bfb3781ab | |||
d7d0c6f822 | |||
2bea18dc3c | |||
f998f2d956 | |||
faa77ee5fb | |||
88ec463284 | |||
b7df71d7d9 | |||
6a28dbd2c4 | |||
010f7fa1fe | |||
209f98594f | |||
54121c99a3 | |||
f6f1370edf | |||
d5863485f9 | |||
afc88d316b | |||
b141279811 | |||
3c8afb0609 | |||
1997ea25d5 | |||
f4b49eecd4 | |||
a4493ec964 | |||
af8bda9e92 | |||
06d252e4ca | |||
67be456bb0 | |||
aa5e225148 | |||
367f46fac8 | |||
d2f14093ec | |||
43ed621879 | |||
15c8134d13 | |||
c2b8f71467 | |||
a6b91c3a14 | |||
164cfbfd0d | |||
0bb340e96e | |||
f0447dc455 | |||
626bbfa7a4 | |||
169a900f01 | |||
d0992eaf54 | |||
fc21d757c3 | |||
54363ee919 | |||
fdad3b9997 | |||
4ad826ebe8 | |||
f5e1e9fdd9 | |||
82b232d0e5 | |||
c8c1fe5367 | |||
71128e0244 | |||
453bcaa1f6 | |||
48898ab1d4 | |||
a095520d0d | |||
2e0c6fa6a5 | |||
bfbc0861df | |||
3a500f3f28 | |||
df8094c39c | |||
448fd0e884 | |||
4717b4549e | |||
57a8d72f1c | |||
7e57617e04 | |||
37ddd643ac | |||
bcf3fef303 | |||
7ac4d24106 | |||
93e5bce778 | |||
d48beba307 | |||
760338496c | |||
b52e7a3078 | |||
78c5b6b2a5 | |||
60a3c38951 | |||
4763033f24 | |||
3b0570d21c | |||
16bf478d1a | |||
5bf181b6d1 | |||
21b2e5d194 | |||
759afcf3ca | |||
d48c7844a4 | |||
7d8caa8df7 | |||
62f53930da | |||
9a45cbb679 | |||
8e5a10f6d8 | |||
10c57d2272 | |||
67d4d0f898 | |||
97e0d04842 | |||
3ba30ede92 | |||
1035e411ab | |||
d5ae4b7ec9 | |||
111d040cf9 | |||
8cc594d170 | |||
d8a8bed68d | |||
eedbd954bd | |||
0eb8366027 | |||
894135104b | |||
7b2e408efc | |||
e4115c122e | |||
537b16949e | |||
ca60ceb2a7 | |||
0fad12fea5 | |||
6cd2c23aac | |||
512baaa43f | |||
d097fcc973 | |||
621dbd459c | |||
840ab4b0c4 | |||
904be34a87 | |||
b7fc6fcc38 | |||
55c6e40d6d | |||
4dfb015057 | |||
e40a0ba2bb | |||
fd48f10df9 | |||
6a54e7fef7 | |||
5c4d6ed140 | |||
9ed1be3594 | |||
c5ce582678 | |||
2050083bce | |||
92e6bdb562 | |||
93e70c38b7 | |||
45b96179a5 | |||
a29a534a40 | |||
8e2297359c | |||
92ba7248ef | |||
f657d37cbd | |||
9e312f60bf | |||
85f72b78f7 | |||
40acb67ceb | |||
3ae8100bda | |||
1a3dc41edf | |||
27f9b8a04e | |||
86669a491a | |||
b111d33b04 | |||
ea5720d1c8 | |||
53675122c6 | |||
4ba7997bc1 | |||
19c446d267 | |||
1abb9ac378 | |||
f9c7492726 | |||
6ece6ca52a | |||
6a2c863fcc | |||
cf69273de1 | |||
fa99b7fd11 | |||
9c5653b52e | |||
88ad8523a0 | |||
a15f59fbd1 | |||
188470a043 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -86,4 +86,5 @@ app/schemas/
|
|||||||
|
|
||||||
signatures/
|
signatures/
|
||||||
|
|
||||||
app/.cxx
|
app/.cxx
|
||||||
|
/i18n/
|
||||||
|
16
.idea/codeStyles/Project.xml
generated
16
.idea/codeStyles/Project.xml
generated
@ -1,6 +1,10 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
|
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
@ -11,7 +15,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:android</NAME>
|
<NAME>xmlns:android</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -22,7 +25,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:.*</NAME>
|
<NAME>xmlns:.*</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -34,7 +36,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:id</NAME>
|
<NAME>.*:id</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -45,7 +46,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:name</NAME>
|
<NAME>.*:name</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -56,7 +56,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>name</NAME>
|
<NAME>name</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -67,7 +66,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>style</NAME>
|
<NAME>style</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -78,7 +76,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -90,7 +87,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -102,7 +98,6 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -112,5 +107,8 @@
|
|||||||
</rules>
|
</rules>
|
||||||
</arrangement>
|
</arrangement>
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
</code_scheme>
|
</code_scheme>
|
||||||
</component>
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
17
.idea/compiler.xml
generated
Normal file
17
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="1.7">
|
||||||
|
<module name="annotation" target="1.7" />
|
||||||
|
<module name="codegen" target="1.7" />
|
||||||
|
<module name="Szkolny.eu.agendacalendarview" target="11" />
|
||||||
|
<module name="Szkolny.eu.app" target="11" />
|
||||||
|
<module name="Szkolny.eu.cafebar" target="11" />
|
||||||
|
<module name="Szkolny.eu.material-about-library" target="11" />
|
||||||
|
<module name="Szkolny.eu.mhttp" target="11" />
|
||||||
|
<module name="Szkolny.eu.nachos" target="11" />
|
||||||
|
<module name="Szkolny.eu.szkolny-font" target="11" />
|
||||||
|
<module name="Szkolny.eu.wear" target="11" />
|
||||||
|
</bytecodeTargetLevel>
|
||||||
|
</component>
|
||||||
|
</project>
|
2
.idea/discord.xml
generated
2
.idea/discord.xml
generated
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DiscordProjectSettings">
|
<component name="DiscordProjectSettings">
|
||||||
<option name="show" value="true" />
|
<option name="show" value="PROJECT_FILES" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectNotificationSettings">
|
<component name="ProjectNotificationSettings">
|
||||||
<option name="askShowProject" value="false" />
|
<option name="askShowProject" value="false" />
|
||||||
|
10
.idea/jarRepositories.xml
generated
10
.idea/jarRepositories.xml
generated
@ -41,5 +41,15 @@
|
|||||||
<option name="name" value="MavenRepo" />
|
<option name="name" value="MavenRepo" />
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven4" />
|
||||||
|
<option name="name" value="maven4" />
|
||||||
|
<option name="url" value="https://dl.bintray.com/undervoid/Powerpermission" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven4" />
|
||||||
|
<option name="name" value="maven4" />
|
||||||
|
<option name="url" value="https://dl.bintray.com/undervoid/PowerPermission" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -11,7 +11,6 @@
|
|||||||
<item index="1" class="java.lang.String" itemvalue="org.greenrobot.eventbus.Subscribe" />
|
<item index="1" class="java.lang.String" itemvalue="org.greenrobot.eventbus.Subscribe" />
|
||||||
</list>
|
</list>
|
||||||
</component>
|
</component>
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="NullableNotNullManager">
|
<component name="NullableNotNullManager">
|
||||||
<option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
|
<option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
|
||||||
<option name="myDefaultNotNull" value="androidx.annotation.RecentlyNonNull" />
|
<option name="myDefaultNotNull" value="androidx.annotation.RecentlyNonNull" />
|
||||||
@ -51,7 +50,7 @@
|
|||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
1
.idea/runConfigurations.xml
generated
1
.idea/runConfigurations.xml
generated
@ -3,6 +3,7 @@
|
|||||||
<component name="RunConfigurationProducerService">
|
<component name="RunConfigurationProducerService">
|
||||||
<option name="ignoredProducers">
|
<option name="ignoredProducers">
|
||||||
<set>
|
<set>
|
||||||
|
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||||
|
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||||||
//apply plugin: 'me.tatarka.retrolambda'
|
//apply plugin: 'me.tatarka.retrolambda'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
|
|
||||||
android {
|
android {
|
||||||
lintOptions {
|
lintOptions {
|
||||||
@ -12,7 +12,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion setup.targetSdk
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
// Google libraries
|
// Google libraries
|
||||||
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
|
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
|
||||||
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
|
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
|
||||||
implementation "com.google.android.material:material:${googleMaterial}"
|
implementation "com.google.android.material:material:${versions.material}"
|
||||||
|
|
||||||
// other libraries
|
// other libraries
|
||||||
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
||||||
|
1
annotation/.gitignore
vendored
Normal file
1
annotation/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
29
annotation/build.gradle
Normal file
29
annotation/build.gradle
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'java-library'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = "7"
|
||||||
|
targetCompatibility = "7"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.annotation
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@MustBeDocumented
|
||||||
|
annotation class SelectiveDao(
|
||||||
|
val db: KClass<*>
|
||||||
|
)
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.annotation
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@MustBeDocumented
|
||||||
|
annotation class UpdateSelective(
|
||||||
|
val primaryKeys: Array<String>,
|
||||||
|
val skippedColumns: Array<String> = []
|
||||||
|
)
|
@ -1,13 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
apply plugin: 'io.fabric'
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
}
|
}
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'pl.szczodrzynski.edziennik'
|
applicationId 'pl.szczodrzynski.edziennik'
|
||||||
minSdkVersion setup.minSdk
|
minSdkVersion setup.minSdk
|
||||||
@ -53,10 +54,11 @@ android {
|
|||||||
lintOptions {
|
lintOptions {
|
||||||
checkReleaseBuilds false
|
checkReleaseBuilds false
|
||||||
}
|
}
|
||||||
dataBinding {
|
buildFeatures {
|
||||||
enabled = true
|
dataBinding = true
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
sourceCompatibility '1.8'
|
sourceCompatibility '1.8'
|
||||||
targetCompatibility '1.8'
|
targetCompatibility '1.8'
|
||||||
}
|
}
|
||||||
@ -74,6 +76,7 @@ android {
|
|||||||
version "3.10.2"
|
version "3.10.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ndkVersion '21.3.6528147'
|
||||||
}
|
}
|
||||||
|
|
||||||
/*task finalizeBundleDebug(type: Copy) {
|
/*task finalizeBundleDebug(type: Copy) {
|
||||||
@ -103,7 +106,9 @@ tasks.whenTaskAdded { task ->
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
|
||||||
annotationProcessor "androidx.room:room-compiler:${versions.room}"
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
|
||||||
|
|
||||||
|
kapt "androidx.room:room-compiler:${versions.room}"
|
||||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
||||||
|
|
||||||
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
||||||
@ -113,7 +118,7 @@ dependencies {
|
|||||||
implementation "androidx.core:core-ktx:${versions.ktx}"
|
implementation "androidx.core:core-ktx:${versions.ktx}"
|
||||||
implementation "androidx.gridlayout:gridlayout:${versions.gridLayout}"
|
implementation "androidx.gridlayout:gridlayout:${versions.gridLayout}"
|
||||||
implementation "androidx.legacy:legacy-support-v4:${versions.legacy}"
|
implementation "androidx.legacy:legacy-support-v4:${versions.legacy}"
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata:${versions.lifecycle}"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.lifecycle}"
|
||||||
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
|
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
|
||||||
implementation "androidx.room:room-runtime:${versions.room}"
|
implementation "androidx.room:room-runtime:${versions.room}"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"
|
||||||
@ -127,6 +132,7 @@ dependencies {
|
|||||||
implementation "com.mikepenz:iconics-core:${versions.iconics}"
|
implementation "com.mikepenz:iconics-core:${versions.iconics}"
|
||||||
implementation "com.mikepenz:iconics-views:${versions.iconics}"
|
implementation "com.mikepenz:iconics-views:${versions.iconics}"
|
||||||
implementation "com.mikepenz:community-material-typeface:${versions.font_cmd}@aar"
|
implementation "com.mikepenz:community-material-typeface:${versions.font_cmd}@aar"
|
||||||
|
implementation "com.mikepenz:materialize:1.2.1"
|
||||||
|
|
||||||
implementation "com.github.kuba2k2:NavLib:${versions.navlib}"
|
implementation "com.github.kuba2k2:NavLib:${versions.navlib}"
|
||||||
|
|
||||||
@ -135,7 +141,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation "cat.ereza:customactivityoncrash:2.2.0"
|
implementation "cat.ereza:customactivityoncrash:2.2.0"
|
||||||
implementation "com.applandeo:material-calendar-view:1.5.0"
|
implementation "com.applandeo:material-calendar-view:1.5.0"
|
||||||
implementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
|
implementation 'com.google.firebase:firebase-crashlytics:17.3.1'
|
||||||
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
||||||
implementation "com.evernote:android-job:1.2.6"
|
implementation "com.evernote:android-job:1.2.6"
|
||||||
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2"
|
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2"
|
||||||
@ -143,7 +149,11 @@ dependencies {
|
|||||||
implementation("com.github.ozodrukh:CircularReveal:2.0.1@aar") {transitive = true}
|
implementation("com.github.ozodrukh:CircularReveal:2.0.1@aar") {transitive = true}
|
||||||
implementation "com.heinrichreimersoftware:material-intro:1.5.8" // do not update
|
implementation "com.heinrichreimersoftware:material-intro:1.5.8" // do not update
|
||||||
implementation "com.jaredrummler:colorpicker:1.0.2"
|
implementation "com.jaredrummler:colorpicker:1.0.2"
|
||||||
implementation "com.squareup.okhttp3:okhttp:3.12.2"
|
implementation("com.squareup.okhttp3:okhttp") {
|
||||||
|
version {
|
||||||
|
strictly "3.12.13"
|
||||||
|
}
|
||||||
|
}
|
||||||
implementation "com.theartofdev.edmodo:android-image-cropper:2.8.0" // do not update
|
implementation "com.theartofdev.edmodo:android-image-cropper:2.8.0" // do not update
|
||||||
implementation "com.wdullaer:materialdatetimepicker:4.1.2"
|
implementation "com.wdullaer:materialdatetimepicker:4.1.2"
|
||||||
implementation "com.yuyh.json:jsonviewer:1.0.6"
|
implementation "com.yuyh.json:jsonviewer:1.0.6"
|
||||||
@ -151,7 +161,7 @@ dependencies {
|
|||||||
implementation "me.grantland:autofittextview:0.2.1"
|
implementation "me.grantland:autofittextview:0.2.1"
|
||||||
implementation "me.leolin:ShortcutBadger:1.1.22@aar"
|
implementation "me.leolin:ShortcutBadger:1.1.22@aar"
|
||||||
implementation "org.greenrobot:eventbus:3.1.1"
|
implementation "org.greenrobot:eventbus:3.1.1"
|
||||||
implementation "org.jsoup:jsoup:1.10.1"
|
implementation "org.jsoup:jsoup:1.12.1"
|
||||||
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.15"
|
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.15"
|
||||||
//implementation "se.emilsjolander:stickylistheaders:2.7.0"
|
//implementation "se.emilsjolander:stickylistheaders:2.7.0"
|
||||||
implementation 'com.github.edisonw:StickyListHeaders:master-SNAPSHOT@aar'
|
implementation 'com.github.edisonw:StickyListHeaders:master-SNAPSHOT@aar'
|
||||||
@ -165,8 +175,8 @@ dependencies {
|
|||||||
//implementation project(":Navigation")
|
//implementation project(":Navigation")
|
||||||
implementation project(":szkolny-font")
|
implementation project(":szkolny-font")
|
||||||
|
|
||||||
debugImplementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
|
implementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
|
||||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
|
//releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
|
||||||
|
|
||||||
//implementation 'com.github.wulkanowy:uonet-request-signer:master-SNAPSHOT'
|
//implementation 'com.github.wulkanowy:uonet-request-signer:master-SNAPSHOT'
|
||||||
//implementation 'com.github.kuba2k2.uonet-request-signer:android:master-63f094b14a-1'
|
//implementation 'com.github.kuba2k2.uonet-request-signer:android:master-63f094b14a-1'
|
||||||
@ -174,6 +184,7 @@ dependencies {
|
|||||||
//implementation "org.redundent:kotlin-xml-builder:1.5.3"
|
//implementation "org.redundent:kotlin-xml-builder:1.5.3"
|
||||||
|
|
||||||
implementation "io.github.wulkanowy:signer-android:0.1.1"
|
implementation "io.github.wulkanowy:signer-android:0.1.1"
|
||||||
|
implementation 'com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31'
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime-ktx:${versions.work}"
|
implementation "androidx.work:work-runtime-ktx:${versions.work}"
|
||||||
|
|
||||||
@ -187,6 +198,23 @@ dependencies {
|
|||||||
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
||||||
|
|
||||||
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
||||||
|
|
||||||
|
implementation "io.coil-kt:coil:0.9.2"
|
||||||
|
|
||||||
|
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
||||||
|
|
||||||
|
implementation project(":annotation")
|
||||||
|
kapt project(":codegen")
|
||||||
|
|
||||||
|
implementation 'com.google.android:flexbox:2.0.1'
|
||||||
|
|
||||||
|
implementation 'com.qifan.powerpermission:powerpermission:1.3.0'
|
||||||
|
implementation 'com.qifan.powerpermission:powerpermission-coroutines:1.3.0'
|
||||||
|
|
||||||
|
implementation 'com.github.kuba2k2.FSLogin:lib:2.0.0'
|
||||||
|
implementation 'pl.droidsonroids:jspoon:1.3.2'
|
||||||
|
implementation "com.squareup.retrofit2:converter-scalars:2.8.1"
|
||||||
|
implementation "pl.droidsonroids.retrofit2:converter-jspoon:1.3.2"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -24,11 +24,18 @@
|
|||||||
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; }
|
-keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; }
|
-keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; }
|
||||||
|
-keep class pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; }
|
-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; }
|
||||||
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||||
|
|
||||||
|
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
|
||||||
|
-keepclassmembernames class androidx.appcompat.view.menu.StandardMenuPopup { private *; }
|
||||||
|
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }
|
||||||
|
|
||||||
|
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
||||||
|
|
||||||
-keep class .R
|
-keep class .R
|
||||||
-keep class **.R$* {
|
-keep class **.R$* {
|
||||||
@ -57,5 +64,9 @@
|
|||||||
|
|
||||||
-keep class pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing { public final byte[] pleaseStopRightNow(java.lang.String, long); }
|
-keep class pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing { public final byte[] pleaseStopRightNow(java.lang.String, long); }
|
||||||
|
|
||||||
-keepclassmembernames class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
||||||
-keepclassmembernames class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
||||||
|
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo$Platform { *; }
|
||||||
|
|
||||||
|
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData { *; }
|
||||||
|
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData$Type { *; }
|
||||||
|
BIN
app/sampledata/vulcan/edu.lublin.eu.png
Normal file
BIN
app/sampledata/vulcan/edu.lublin.eu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
@ -14,6 +14,9 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
<!-- PowerPermission uses minSdk 21, it's safe to override as it is used only in >= 23 -->
|
||||||
|
<uses-sdk tools:overrideLibrary="com.qifan.powerpermission.coroutines, com.qifan.powerpermission.core" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -21,7 +24,6 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme.Dark"
|
android:theme="@style/AppTheme.Dark"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
@ -62,7 +64,7 @@
|
|||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoDisplay">
|
android:theme="@style/AppTheme.Dark.NoDisplay">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@ -80,10 +82,11 @@
|
|||||||
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
<activity android:name=".ui.widgets.LessonDialogActivity"
|
<activity android:name=".ui.widgets.LessonDialogActivity"
|
||||||
|
android:label=""
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoDisplay" />
|
android:theme="@style/AppTheme.Dark.NoDisplay" />
|
||||||
<!-- NOTIFICATIONS -->
|
<!-- NOTIFICATIONS -->
|
||||||
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
||||||
android:label="@string/widget_notifications_title">
|
android:label="@string/widget_notifications_title">
|
||||||
@ -98,7 +101,7 @@
|
|||||||
<service android:name=".ui.widgets.notifications.WidgetNotificationsService"
|
<service android:name=".ui.widgets.notifications.WidgetNotificationsService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
<!-- LUCKY NUMBER -->
|
<!-- LUCKY NUMBER -->
|
||||||
<receiver android:name=".widgets.luckynumber.WidgetLuckyNumber"
|
<receiver android:name=".ui.widgets.luckynumber.WidgetLuckyNumberProvider"
|
||||||
android:label="@string/widget_lucky_number_title">
|
android:label="@string/widget_lucky_number_title">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
@ -131,9 +134,6 @@
|
|||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/AppTheme.Light" />
|
android:theme="@style/AppTheme.Light" />
|
||||||
<activity android:name=".ui.modules.login.LoginLibrusCaptchaActivity"
|
|
||||||
android:theme="@android:style/Theme.Dialog"
|
|
||||||
android:excludeFromRecents="true"/>
|
|
||||||
<activity android:name=".ui.modules.home.CounterActivity"
|
<activity android:name=".ui.modules.home.CounterActivity"
|
||||||
android:theme="@style/AppTheme.Black" />
|
android:theme="@style/AppTheme.Black" />
|
||||||
<activity android:name=".ui.modules.feedback.FeedbackActivity"
|
<activity android:name=".ui.modules.feedback.FeedbackActivity"
|
||||||
@ -141,12 +141,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
||||||
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.webpush.WebPushConfigActivity"
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
|
||||||
android:theme="@style/AppTheme.Dark" />
|
|
||||||
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
||||||
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
@ -165,18 +161,9 @@
|
|||||||
<action android:name="android.intent.action.USER_PRESENT" />
|
<action android:name="android.intent.action.USER_PRESENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.BootReceiver">
|
<receiver android:name=".sync.UpdateDownloaderService$DownloadProgressReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
||||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
<receiver android:name=".sync.FirebaseBroadcastReceiver"
|
|
||||||
android:exported="true"
|
|
||||||
android:permission="com.google.android.c2dm.permission.SEND">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.SzkolnyReceiver"
|
<receiver android:name=".receivers.SzkolnyReceiver"
|
||||||
@ -193,16 +180,22 @@
|
|||||||
____) | __/ | \ V /| | (_| __/\__ \
|
____) | __/ | \ V /| | (_| __/\__ \
|
||||||
|_____/ \___|_| \_/ |_|\___\___||___/
|
|_____/ \___|_| \_/ |_|\___\___||___/
|
||||||
-->
|
-->
|
||||||
<service android:name=".sync.MyFirebaseMessagingService"
|
<!--<service android:name=".sync.MyFirebaseMessagingService"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>-->
|
||||||
<service android:name=".receivers.BootReceiver$NotificationActionService" />
|
|
||||||
<service android:name=".Notifier$GetDataRetryService" />
|
|
||||||
<service android:name=".data.api.ApiService" />
|
<service android:name=".data.api.ApiService" />
|
||||||
|
<service android:name=".data.firebase.MyFirebaseService"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter android:priority="10000000">
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
<service android:name=".sync.UpdateDownloaderService" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
_____ _ _
|
_____ _ _
|
||||||
|
@ -1,38 +1,10 @@
|
|||||||
<h3>Wersja 4.0-beta.2, 2020-01-06</h3>
|
<h3>Wersja 4.6-beta.1, 2021-02-25</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkosć oraz poprawność pobieranych danych.</li>
|
<li>Vulcan: dodano możliwość logowania adresem e-mail lub nazwą użytkownika.</li>
|
||||||
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
<li>Vulcan: dodano obsługę załączników w wiadomościach i zadaniach domowych.</li>
|
||||||
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
<li>Zalecane jest zalogowanie się ponownie.</li>
|
||||||
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
|
||||||
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
|
||||||
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
|
||||||
<li>Łatwiejsze dodawanie własnych wydarzeń</li>
|
|
||||||
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
|
||||||
<li>Częściowa <b>Obsługa dziennika EduDziennik</b></li>
|
|
||||||
<li>Librus: opcja logowania w dziennikach <b>Jednostek Samorządu Terytorialnego</b> oraz <b>Oświata w Radomiu</b></li>
|
|
||||||
<li>Librus: <b>poprawione obliczanie frekwencji</b></li>
|
|
||||||
<li>Librus: obsługa Zadań domowych bez posiadania Mobilnych dodatków (przez system Synergia)</li>
|
|
||||||
<li>Lepsze <b>przekazywanie powiadomień na komputer</b> oraz łatwiejsze parowanie</li>
|
|
||||||
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
|
||||||
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
|
||||||
<b>Uwaga.</b> Ponieważ to wersja <i>beta</i>, niektóre funkcje mogą nie działać prawidłowo.<br>
|
|
||||||
Staramy się usuwać takie przypadki, jednak na chwilę obecną mogą występować błędy w:
|
|
||||||
<ul>
|
|
||||||
<li>Wysyłanie wiadomości może czasami nie działać - proszę o zgłaszanie wszystkich błędów na naszym serwerze Discord</li>
|
|
||||||
<li>Widget szczęśliwego numerka</li>
|
|
||||||
<li>Terminarz - brak informacji o odwołanych lekcjach w dialogu</li>
|
|
||||||
</ul>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<i>Okazja ograniczona czasowo:</i> Poczuj prawdziwą zimę, włączając w Ustawieniach widok padającego śniegu!
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Dzięki za korzystanie ze Szkolnego!<br>
|
Dzięki za korzystanie ze Szkolnego!<br>
|
||||||
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>
|
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2021</i>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*secret password - removed for source code publication*/
|
/*secret password - removed for source code publication*/
|
||||||
static toys AES_IV[16] = {
|
static toys AES_IV[16] = {
|
||||||
0xf5, 0xbe, 0x91, 0x89, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
0xe5, 0x07, 0x0f, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||||
|
|
||||||
|
@ -1,714 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ShortcutInfo;
|
|
||||||
import android.content.pm.ShortcutManager;
|
|
||||||
import android.content.pm.Signature;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Icon;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Base64;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
|
||||||
import androidx.work.Configuration;
|
|
||||||
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector;
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor;
|
|
||||||
import com.chuckerteam.chucker.api.RetentionManager;
|
|
||||||
import com.google.android.gms.security.ProviderInstaller;
|
|
||||||
import com.google.firebase.FirebaseApp;
|
|
||||||
import com.google.firebase.FirebaseOptions;
|
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
|
||||||
import com.google.firebase.messaging.FirebaseMessaging;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import com.hypertrack.hyperlog.HyperLog;
|
|
||||||
import com.mikepenz.iconics.Iconics;
|
|
||||||
import com.mikepenz.iconics.IconicsColor;
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable;
|
|
||||||
import com.mikepenz.iconics.IconicsSize;
|
|
||||||
import com.mikepenz.iconics.typeface.IIcon;
|
|
||||||
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
|
|
||||||
import cat.ereza.customactivityoncrash.config.CaocConfig;
|
|
||||||
import im.wangchao.mhttp.MHttp;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor;
|
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
|
||||||
import okhttp3.ConnectionSpec;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.TlsVersion;
|
|
||||||
import pl.szczodrzynski.edziennik.config.Config;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.DebugLog;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
|
|
||||||
import pl.szczodrzynski.edziennik.network.NetworkUtils;
|
|
||||||
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
|
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker;
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.DebugLogFormat;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.AppConfig;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.LoginStore.LOGIN_TYPE_MOBIDZIENNIK;
|
|
||||||
|
|
||||||
public class App extends androidx.multidex.MultiDexApplication implements Configuration.Provider {
|
|
||||||
private static final String TAG = "App";
|
|
||||||
public static int profileId = -1;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Configuration getWorkManagerConfiguration() {
|
|
||||||
return new Configuration.Builder()
|
|
||||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final int REQUEST_TIMEOUT = 10 * 1000;
|
|
||||||
|
|
||||||
// notifications
|
|
||||||
//public NotificationManager mNotificationManager;
|
|
||||||
//public final String NOTIFICATION_CHANNEL_ID_UPDATES = "4566";
|
|
||||||
//public String NOTIFICATION_CHANNEL_NAME_UPDATES;
|
|
||||||
public Notifier notifier;
|
|
||||||
|
|
||||||
public static final String APP_URL = "://edziennik.szczodrzynski.pl/app/";
|
|
||||||
|
|
||||||
public ShortcutManager shortcutManager;
|
|
||||||
|
|
||||||
public PermissionChecker permissionChecker;
|
|
||||||
|
|
||||||
public String signature = "";
|
|
||||||
public String deviceId = "";
|
|
||||||
|
|
||||||
public AppDb db;
|
|
||||||
public void debugLog(String text) {
|
|
||||||
if (!devMode)
|
|
||||||
return;
|
|
||||||
db.debugLogDao().add(new DebugLog(Utils.getCurrentTimeUsingCalendar()+": "+text));
|
|
||||||
}
|
|
||||||
public void debugLogAsync(String text) {
|
|
||||||
if (!devMode)
|
|
||||||
return;
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.debugLogDao().add(new DebugLog(Utils.getCurrentTimeUsingCalendar()+": "+text));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// network & APIs
|
|
||||||
public NetworkUtils networkUtils;
|
|
||||||
public PersistentCookieJar cookieJar;
|
|
||||||
public OkHttpClient http;
|
|
||||||
public OkHttpClient httpLazy;
|
|
||||||
|
|
||||||
public SharedPreferences appSharedPrefs; // sharedPreferences for APPCONFIG + JOBS STORE
|
|
||||||
public AppConfig appConfig; // APPCONFIG: common for all profiles
|
|
||||||
//public AppProfile profile; // current profile
|
|
||||||
public SharedPreferences registerStore; // sharedPreferences for REGISTER
|
|
||||||
//public Register register; // REGISTER for current profile, read from registerStore
|
|
||||||
|
|
||||||
public Profile profile;
|
|
||||||
public Config config;
|
|
||||||
private static Config mConfig;
|
|
||||||
public static Config getConfig() {
|
|
||||||
return mConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other stuff
|
|
||||||
public Gson gson;
|
|
||||||
public String requestScheme = "https";
|
|
||||||
public boolean unreadBadgesAvailable = true;
|
|
||||||
|
|
||||||
public static boolean devMode = false;
|
|
||||||
|
|
||||||
public static final boolean UPDATES_ON_PLAY_STORE = true;
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
|
||||||
public Icon getDesktopIconFromIconics(IIcon icon) {
|
|
||||||
final IconicsDrawable drawable = new IconicsDrawable(mContext, icon)
|
|
||||||
.color(IconicsColor.colorInt(Color.WHITE))
|
|
||||||
.size(IconicsSize.dp(48))
|
|
||||||
.padding(IconicsSize.dp(8))
|
|
||||||
.backgroundColor(IconicsColor.colorRes(R.color.colorPrimaryDark))
|
|
||||||
.roundedCorners(IconicsSize.dp(10));
|
|
||||||
//drawable.setStyle(Paint.Style.FILL);
|
|
||||||
final Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
|
||||||
final Canvas canvas = new Canvas(bitmap);
|
|
||||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
|
||||||
drawable.draw(canvas);
|
|
||||||
|
|
||||||
return Icon.createWithBitmap(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
|
||||||
CaocConfig.Builder.create()
|
|
||||||
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM) //default: CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM
|
|
||||||
.enabled(true) //default: true
|
|
||||||
.showErrorDetails(true) //default: true
|
|
||||||
.showRestartButton(true) //default: true
|
|
||||||
.logErrorOnRestart(true) //default: true
|
|
||||||
.trackActivities(true) //default: false
|
|
||||||
.minTimeBetweenCrashesMs(2000) //default: 3000
|
|
||||||
.errorDrawable(R.drawable.ic_rip) //default: bug image
|
|
||||||
.restartActivity(MainActivity.class) //default: null (your app's launch activity)
|
|
||||||
.errorActivity(CrashActivity.class) //default: null (default error activity)
|
|
||||||
//.eventListener(new YourCustomEventListener()) //default: null
|
|
||||||
.apply();
|
|
||||||
mContext = this;
|
|
||||||
db = AppDb.getDatabase(this);
|
|
||||||
gson = new Gson();
|
|
||||||
networkUtils = new NetworkUtils(this);
|
|
||||||
|
|
||||||
config = new Config(db);
|
|
||||||
config.migrate(this);
|
|
||||||
mConfig = config;
|
|
||||||
|
|
||||||
Iconics.init(getApplicationContext());
|
|
||||||
Iconics.registerFont(SzkolnyFont.INSTANCE);
|
|
||||||
|
|
||||||
notifier = new Notifier(this);
|
|
||||||
permissionChecker = new PermissionChecker(mContext);
|
|
||||||
|
|
||||||
deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
|
|
||||||
|
|
||||||
cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(this));
|
|
||||||
|
|
||||||
appSharedPrefs = getSharedPreferences(getString(R.string.preference_file_global), Context.MODE_PRIVATE);
|
|
||||||
|
|
||||||
loadConfig();
|
|
||||||
|
|
||||||
Signing.INSTANCE.getCert(this);
|
|
||||||
|
|
||||||
Themes.INSTANCE.setThemeInt(config.getUi().getTheme());
|
|
||||||
|
|
||||||
try {
|
|
||||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
|
|
||||||
for (Signature signature: packageInfo.signatures) {
|
|
||||||
byte[] signatureBytes = signature.toByteArray();
|
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
|
||||||
md.update(signatureBytes);
|
|
||||||
this.signature = Base64.encodeToString(md.digest(), Base64.NO_WRAP);
|
|
||||||
//Log.d(TAG, "Signature is "+this.signature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("f054761fbdb6a238".equals(deviceId) || BuildConfig.DEBUG) {
|
|
||||||
devMode = true;
|
|
||||||
}
|
|
||||||
else if (config.getDevModePassword() != null) {
|
|
||||||
checkDevModePassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
|
|
||||||
.cache(null)
|
|
||||||
.followRedirects(true)
|
|
||||||
.followSslRedirects(true)
|
|
||||||
.retryOnConnectionFailure(true)
|
|
||||||
.cookieJar(cookieJar)
|
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(20, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(40, TimeUnit.SECONDS);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
ProviderInstaller.installIfNeeded(this);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Play Services not found or outdated");
|
|
||||||
X509TrustManager x509TrustManager = null;
|
|
||||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
|
||||||
trustManagerFactory.init((KeyStore) null);
|
|
||||||
for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) {
|
|
||||||
if (trustManager instanceof X509TrustManager)
|
|
||||||
x509TrustManager = (X509TrustManager) trustManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSLContext sc = SSLContext.getInstance("TLSv1.2");
|
|
||||||
sc.init(null, null, null);
|
|
||||||
httpBuilder.sslSocketFactory(new TLSSocketFactory(sc.getSocketFactory()), x509TrustManager);
|
|
||||||
|
|
||||||
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_0)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_1)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_2)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
List<ConnectionSpec> specs = new ArrayList<>();
|
|
||||||
specs.add(cs);
|
|
||||||
specs.add(ConnectionSpec.COMPATIBLE_TLS);
|
|
||||||
specs.add(ConnectionSpec.CLEARTEXT);
|
|
||||||
|
|
||||||
httpBuilder.connectionSpecs(specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception exc) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App.devMode || BuildConfig.DEBUG) {
|
|
||||||
HyperLog.initialize(this);
|
|
||||||
HyperLog.setLogLevel(Log.VERBOSE);
|
|
||||||
HyperLog.setLogFormat(new DebugLogFormat(this));
|
|
||||||
|
|
||||||
ChuckerCollector chuckerCollector = new ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR);
|
|
||||||
ChuckerInterceptor chuckerInterceptor = new ChuckerInterceptor(this, chuckerCollector);
|
|
||||||
httpBuilder.addInterceptor(chuckerInterceptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
http = httpBuilder.build();
|
|
||||||
httpLazy = http.newBuilder().followRedirects(false).followSslRedirects(false).build();
|
|
||||||
|
|
||||||
MHttp.instance()
|
|
||||||
.customOkHttpClient(http);
|
|
||||||
|
|
||||||
//register = new Register(mContext);
|
|
||||||
|
|
||||||
//profileLoadById(appSharedPrefs.getInt("current_profile_id", 1));
|
|
||||||
|
|
||||||
if (config.getSync().getEnabled()) {
|
|
||||||
SyncWorker.Companion.scheduleNext(this, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SyncWorker.Companion.cancelNext(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.metadataDao().countUnseen().observeForever(count -> {
|
|
||||||
Log.d("MainActivity", "Overall unseen count changed");
|
|
||||||
assert count != null;
|
|
||||||
if (unreadBadgesAvailable) {
|
|
||||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this, count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//new IonCookieManager(mContext);
|
|
||||||
|
|
||||||
new Handler().post(() -> {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
shortcutManager = getSystemService(ShortcutManager.class);
|
|
||||||
|
|
||||||
ShortcutInfo shortcutTimetable = new ShortcutInfo.Builder(mContext, "item_timetable")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_timetable))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon2.cmd_timetable))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutAgenda = new ShortcutInfo.Builder(mContext, "item_agenda")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_agenda))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon.cmd_calendar))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutGrades = new ShortcutInfo.Builder(mContext, "item_grades")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_grades))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon2.cmd_numeric_5_box))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutHomework = new ShortcutInfo.Builder(mContext, "item_homeworks")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_homework))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(SzkolnyFont.Icon.szf_file_document_edit))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutMessages = new ShortcutInfo.Builder(mContext, "item_messages")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_messages))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon.cmd_email))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES ))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcutTimetable, shortcutAgenda, shortcutGrades, shortcutHomework, shortcutMessages));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getAppInstalledTime() == 0) {
|
|
||||||
try {
|
|
||||||
config.setAppInstalledTime(getPackageManager().getPackageInfo(getPackageName(), 0).firstInstallTime);
|
|
||||||
config.setAppRateSnackbarTime(config.getAppInstalledTime() + 7 * 24 * 60 * 60 * 1000);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Task<CapabilityInfo> capabilityInfoTask =
|
|
||||||
Wearable.getCapabilityClient(this)
|
|
||||||
.getCapability("edziennik_wear_app", CapabilityClient.FILTER_REACHABLE);
|
|
||||||
capabilityInfoTask.addOnCompleteListener((task) -> {
|
|
||||||
if (task.isSuccessful()) {
|
|
||||||
CapabilityInfo capabilityInfo = task.getResult();
|
|
||||||
assert capabilityInfo != null;
|
|
||||||
Set<Node> nodes;
|
|
||||||
nodes = capabilityInfo.getNodes();
|
|
||||||
Log.d(TAG, "Nodes "+nodes);
|
|
||||||
|
|
||||||
if (nodes.size() > 0) {
|
|
||||||
Wearable.getMessageClient(this).sendMessage(
|
|
||||||
nodes.toArray(new Node[]{})[0].getId(), "/ping", "Hello world".getBytes());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Capability request failed to return any results.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Wearable.getDataClient(this).addListener(dataEventBuffer -> {
|
|
||||||
Log.d(TAG, "onDataChanged(): " + dataEventBuffer);
|
|
||||||
|
|
||||||
for (DataEvent event : dataEventBuffer) {
|
|
||||||
if (event.getType() == DataEvent.TYPE_CHANGED) {
|
|
||||||
String path = event.getDataItem().getUri().getPath();
|
|
||||||
Log.d(TAG, "Data "+path+ " :: "+Arrays.toString(event.getDataItem().getData()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
FirebaseApp pushMobidziennikApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
|
||||||
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
|
||||||
.build(),
|
|
||||||
"Mobidziennik2"
|
|
||||||
);
|
|
||||||
|
|
||||||
FirebaseApp pushLibrusApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
|
||||||
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
|
||||||
.build(),
|
|
||||||
"Librus"
|
|
||||||
);
|
|
||||||
|
|
||||||
FirebaseApp pushVulcanApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
|
||||||
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
|
||||||
.build(),
|
|
||||||
"Vulcan"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (config.getRunSync()) {
|
|
||||||
config.setRunSync(false);
|
|
||||||
EdziennikTask.Companion.sync().enqueue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final long startTime = System.currentTimeMillis();
|
|
||||||
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for App is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId()+". Time is "+(System.currentTimeMillis() - startTime));
|
|
||||||
config.getSync().setTokenApp(instanceIdResult.getToken());
|
|
||||||
});
|
|
||||||
/*FirebaseInstanceId.getInstance(pushMobidziennikApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Mobidziennik is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_MOBIDZIENNIK, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
});
|
|
||||||
FirebaseInstanceId.getInstance(pushLibrusApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Librus is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_LIBRUS, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
});
|
|
||||||
FirebaseInstanceId.getInstance(pushVulcanApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Vulcan is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
Pair<String, List<Integer>> pair = appConfig.fcmTokens.get(LOGIN_TYPE_VULCAN);
|
|
||||||
if (pair == null || pair.first == null || !pair.first.equals(instanceIdResult.getToken())) {
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_VULCAN, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
|
|
||||||
FirebaseMessaging.getInstance().subscribeToTopic(getPackageName());
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadConfig()
|
|
||||||
{
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
|
|
||||||
|
|
||||||
if (appSharedPrefs.contains("config")) {
|
|
||||||
// remove old-format config, save the new one and empty the incorrectly-nulled config
|
|
||||||
appConfig = gson.fromJson(appSharedPrefs.getString("config", ""), AppConfig.class);
|
|
||||||
appSharedPrefs.edit().remove("config").apply();
|
|
||||||
saveConfig();
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appSharedPrefs.contains("profiles")) {
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
/*List<Integer> appProfileIds = gson.fromJson(appSharedPrefs.getString("profiles", ""), new TypeToken<List<Integer>>(){}.getType());
|
|
||||||
for (int id: appProfileIds) {
|
|
||||||
AppProfile appProfile = gson.fromJson(appSharedPrefs.getString("profile"+id, ""), AppProfile.class);
|
|
||||||
if (appProfile != null) {
|
|
||||||
appConfig.profiles.add(appProfile);
|
|
||||||
}
|
|
||||||
appSharedPrefsEditor.remove("profile"+id);
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.remove("profiles");
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
//profilesSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Map<String,?> keys = appSharedPrefs.getAll();
|
|
||||||
for (Map.Entry<String,?> entry : keys.entrySet()) {
|
|
||||||
if (entry.getKey().startsWith("app.appConfig.")) {
|
|
||||||
String fieldName = entry.getKey().replace("app.appConfig.", "");
|
|
||||||
|
|
||||||
try {
|
|
||||||
Field field = AppConfig.class.getField(fieldName);
|
|
||||||
Object object;
|
|
||||||
try {
|
|
||||||
object = gson.fromJson(entry.getValue().toString(), field.getGenericType());
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
Log.d(TAG, "For field "+fieldName);
|
|
||||||
e.printStackTrace();
|
|
||||||
object = entry.getValue().toString();
|
|
||||||
}
|
|
||||||
if (object != null)
|
|
||||||
field.set(appConfig, object);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Log.w(TAG, "Should remove app.appConfig."+fieldName);
|
|
||||||
//appSharedPrefs.edit().remove("app.appConfig."+fieldName).apply(); TODO migration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (appConfig.lastAppVersion > BuildConfig.VERSION_CODE) {
|
|
||||||
BootReceiver br = new BootReceiver();
|
|
||||||
Intent i = new Intent();
|
|
||||||
//i.putExtra("UserChecked", true);
|
|
||||||
br.onReceive(getContext(), i);
|
|
||||||
Toast.makeText(mContext, R.string.warning_older_version_running, Toast.LENGTH_LONG).show();
|
|
||||||
//Toast.makeText(mContext, "Zaktualizuj aplikację.", Toast.LENGTH_LONG).show();
|
|
||||||
//System.exit(0);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (appConfig == null) {
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void saveConfig()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
appConfig.savePending = false;
|
|
||||||
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
|
|
||||||
JsonObject appConfigJson = gson.toJsonTree(appConfig).getAsJsonObject();
|
|
||||||
for (Map.Entry<String, JsonElement> entry : appConfigJson.entrySet()) {
|
|
||||||
String jsonObj;
|
|
||||||
jsonObj = entry.getValue().toString();
|
|
||||||
/*if (entry.getValue().isJsonObject()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonObject().toString();
|
|
||||||
}
|
|
||||||
else if (entry.getValue().isJsonArray()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonArray().toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jsonObj = entry.getValue().toString();
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.putString("app.appConfig." + entry.getKey(), jsonObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
}
|
|
||||||
catch (ConcurrentModificationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//appSharedPrefs.edit().putString("config", gson.toJson(appConfig)).apply();
|
|
||||||
}
|
|
||||||
public void saveConfig(String ... fieldNames)
|
|
||||||
{
|
|
||||||
appConfig.savePending = false;
|
|
||||||
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
|
|
||||||
for (String fieldName: fieldNames) {
|
|
||||||
try {
|
|
||||||
Object object = AppConfig.class.getField(fieldName).get(appConfig);
|
|
||||||
appSharedPrefsEditor.putString("app.appConfig."+fieldName, gson.toJson(object));
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ConcurrentModificationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
//appSharedPrefs.edit().putString("config", gson.toJson(appConfig)).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileSave() {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileSaveAsync() {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public void profileSaveAsync(Profile profile) {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileLoadById(int id) {
|
|
||||||
profileLoadById(id, false);
|
|
||||||
}
|
|
||||||
public void profileLoadById(int id, boolean loadedLast) {
|
|
||||||
//Log.d(TAG, "Loading ID "+id);
|
|
||||||
/*if (profile == null) {
|
|
||||||
profile = profileNew();
|
|
||||||
AppDb.profileId = profile.id;
|
|
||||||
appSharedPrefs.edit().putInt("current_profile_id", profile.id).apply();
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile == null || profile.getId() != id) {
|
|
||||||
profile = db.profileDao().getByIdNow(id);
|
|
||||||
/*if (profile == null) {
|
|
||||||
profileLoadById(id);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile != null) {
|
|
||||||
MainActivity.Companion.setUseOldMessages(profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK && appConfig.mobidziennikOldMessages == 1);
|
|
||||||
profileId = profile.getId();
|
|
||||||
appSharedPrefs.edit().putInt("current_profile_id", profile.getId()).apply();
|
|
||||||
config.setProfile(profileId);
|
|
||||||
}
|
|
||||||
else if (!loadedLast) {
|
|
||||||
profileLoadById(profileLastId(), true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
profileId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public void profileRemove(int id)
|
|
||||||
{
|
|
||||||
Profile profile = db.profileDao().getFullByIdNow(id);
|
|
||||||
|
|
||||||
if (profile.id == profile.loginStoreId) {
|
|
||||||
// this profile is the owner of the login store
|
|
||||||
// we need to check if any other profile is using it
|
|
||||||
List<Integer> transferProfileIds = db.profileDao().getIdsByLoginStoreIdNow(profile.loginStoreId);
|
|
||||||
if (transferProfileIds.size() == 1) {
|
|
||||||
// this login store is free of users, remove it along with the profile
|
|
||||||
db.loginStoreDao().remove(profile.loginStoreId);
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
else if (transferProfileIds.size() > 1) {
|
|
||||||
transferProfileIds.remove(transferProfileIds.indexOf(profile.id));
|
|
||||||
// someone is using the store
|
|
||||||
// we need to transfer it to the firstProfileId
|
|
||||||
db.loginStoreDao().changeId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
db.profileDao().changeStoreId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else, the profile uses a store that it doesn't own
|
|
||||||
// leave the store and go on with removing
|
|
||||||
|
|
||||||
Log.d(TAG, "Before removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
db.profileDao().remove(profile.id);
|
|
||||||
Log.d(TAG, "After removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
|
|
||||||
*//*int newId = 1;
|
|
||||||
if (appConfig.profiles.size() > 0) {
|
|
||||||
newId = appConfig.profiles.get(appConfig.profiles.size() - 1).id;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "New ID: "+newId);
|
|
||||||
//Toast.makeText(mContext, "selected new id "+newId, Toast.LENGTH_SHORT).show();
|
|
||||||
profileLoadById(newId);*//*
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public int profileFirstId() {
|
|
||||||
Integer id = db.profileDao().getFirstId();
|
|
||||||
return id == null ? 1 : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int profileLastId() {
|
|
||||||
Integer id = db.profileDao().getLastId();
|
|
||||||
return id == null ? 1 : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Context getContext()
|
|
||||||
{
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkDevModePassword() {
|
|
||||||
try {
|
|
||||||
devMode = Utils.AESCrypt.decrypt("nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=", config.getDevModePassword()).equals("ok here you go it's enabled now")
|
|
||||||
|| BuildConfig.DEBUG;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
devMode = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -4,20 +4,79 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.ShortcutInfo
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.multidex.MultiDexApplication
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||||
import kotlinx.coroutines.Job
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||||
|
import com.chuckerteam.chucker.api.RetentionManager
|
||||||
|
import com.google.firebase.FirebaseApp
|
||||||
|
import com.google.firebase.FirebaseOptions
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceId
|
||||||
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.hypertrack.hyperlog.HyperLog
|
||||||
|
import com.mikepenz.iconics.Iconics
|
||||||
|
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||||
|
import im.wangchao.mhttp.MHttp
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import me.leolin.shortcutbadger.ShortcutBadger
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.network.NetworkUtils
|
||||||
|
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
|
||||||
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||||
|
import pl.szczodrzynski.edziennik.utils.*
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScope {
|
class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
lateinit var db: AppDb
|
||||||
|
val config: Config by lazy { Config(db) }
|
||||||
|
var profile: Profile by mutableLazy { Profile(0, 0, 0, "") }
|
||||||
|
val profileId
|
||||||
|
get() = profile.id
|
||||||
|
|
||||||
|
var debugMode = false
|
||||||
var devMode = false
|
var devMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//lateinit var db: AppDb
|
val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
|
||||||
//val config by lazy { Config(db); // TODO migrate }
|
val userActionManager by lazy { UserActionManager(this) }
|
||||||
|
val gradesManager by lazy { GradesManager(this) }
|
||||||
|
val timetableManager by lazy { TimetableManager(this) }
|
||||||
|
val eventManager by lazy { EventManager(this) }
|
||||||
|
val permissionManager by lazy { PermissionManager(this) }
|
||||||
|
val attendanceManager by lazy { AttendanceManager(this) }
|
||||||
|
|
||||||
|
val db
|
||||||
|
get() = App.db
|
||||||
|
val config
|
||||||
|
get() = App.config
|
||||||
|
val profile
|
||||||
|
get() = App.profile
|
||||||
|
val profileId
|
||||||
|
get() = App.profileId
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
@ -26,11 +85,9 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
.setMinimumLoggingLevel(Log.VERBOSE)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
/*val preferences by lazy { getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE) }
|
|
||||||
val notifier by lazy { Notifier(this) }
|
|
||||||
val permissionChecker by lazy { PermissionChecker(this) }
|
val permissionChecker by lazy { PermissionChecker(this) }
|
||||||
|
val networkUtils by lazy { NetworkUtils(this) }
|
||||||
lateinit var profile: ProfileFull
|
val gson by lazy { Gson() }
|
||||||
|
|
||||||
/* _ _ _______ _______ _____
|
/* _ _ _______ _______ _____
|
||||||
| | | |__ __|__ __| __ \
|
| | | |__ __|__ __| __ \
|
||||||
@ -45,16 +102,16 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.followSslRedirects(true)
|
.followSslRedirects(true)
|
||||||
.retryOnConnectionFailure(true)
|
.retryOnConnectionFailure(true)
|
||||||
.cookieJar(cookieJar)
|
.cookieJar(cookieJar)
|
||||||
.connectTimeout(20, TimeUnit.SECONDS)
|
.connectTimeout(15, TimeUnit.SECONDS)
|
||||||
.writeTimeout(5, TimeUnit.SECONDS)
|
.writeTimeout(10, TimeUnit.SECONDS)
|
||||||
.readTimeout(10, TimeUnit.SECONDS)
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
builder.installHttpsSupport()
|
builder.installHttpsSupport(this)
|
||||||
|
|
||||||
if (devMode || BuildConfig.DEBUG) {
|
if (devMode || BuildConfig.DEBUG) {
|
||||||
HyperLog.initialize(this)
|
HyperLog.initialize(this)
|
||||||
HyperLog.setLogLevel(Log.VERBOSE)
|
HyperLog.setLogLevel(Log.VERBOSE)
|
||||||
HyperLog.setLogFormat(DebugLogFormat(this))
|
HyperLog.setLogFormat(DebugLogFormat(this))
|
||||||
val chuckerCollector = ChuckerCollector(this, true, Period.ONE_HOUR)
|
val chuckerCollector = ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
|
||||||
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
||||||
builder.addInterceptor(chuckerInterceptor)
|
builder.addInterceptor(chuckerInterceptor)
|
||||||
}
|
}
|
||||||
@ -67,7 +124,7 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.followSslRedirects(false)
|
.followSslRedirects(false)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
val cookieJar by lazy { PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(this)) }
|
val cookieJar by lazy { DumbCookieJar(this) }
|
||||||
|
|
||||||
/* _____ _ _
|
/* _____ _ _
|
||||||
/ ____(_) | |
|
/ ____(_) | |
|
||||||
@ -77,22 +134,7 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
private val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
||||||
private val signature: String by lazy {
|
|
||||||
var str = ""
|
|
||||||
try {
|
|
||||||
val packageInfo: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
|
|
||||||
for (signature in packageInfo.signatures) {
|
|
||||||
val signatureBytes = signature.toByteArray()
|
|
||||||
val md = MessageDigest.getInstance("SHA")
|
|
||||||
md.update(signatureBytes)
|
|
||||||
str = Base64.encodeToString(md.digest(), Base64.DEFAULT)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
str
|
|
||||||
}
|
|
||||||
private var unreadBadgesAvailable = true
|
private var unreadBadgesAvailable = true
|
||||||
|
|
||||||
/* _____ _
|
/* _____ _
|
||||||
@ -118,193 +160,240 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.apply()
|
.apply()
|
||||||
Iconics.init(applicationContext)
|
Iconics.init(applicationContext)
|
||||||
Iconics.registerFont(SzkolnyFont)
|
Iconics.registerFont(SzkolnyFont)
|
||||||
db = AppDb.getDatabase(this)
|
App.db = AppDb(this)
|
||||||
Themes.themeInt = config.ui.theme
|
Themes.themeInt = config.ui.theme
|
||||||
|
devMode = config.debugMode
|
||||||
MHttp.instance().customOkHttpClient(http)
|
MHttp.instance().customOkHttpClient(http)
|
||||||
|
|
||||||
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
if (!profileLoadById(config.lastProfileId)) {
|
||||||
if (config.devModePassword != null)
|
db.profileDao().firstId?.let { profileLoadById(it) }
|
||||||
checkDevModePassword()
|
}
|
||||||
|
|
||||||
|
config.ui.language?.let {
|
||||||
|
setLanguage(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
debugMode = BuildConfig.DEBUG
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
devMode = true
|
||||||
|
|
||||||
Signing.getCert(this)
|
Signing.getCert(this)
|
||||||
|
|
||||||
launch { async(Dispatchers.Default) {
|
launch {
|
||||||
if (config.sync.enabled) {
|
withContext(Dispatchers.Default) {
|
||||||
scheduleNext(this@App, false)
|
config.migrate(this@App)
|
||||||
} else {
|
|
||||||
cancelNext(this@App)
|
if (config.devModePassword != null)
|
||||||
|
checkDevModePassword()
|
||||||
|
devMode = debugMode || config.debugMode
|
||||||
|
|
||||||
|
if (config.sync.enabled)
|
||||||
|
SyncWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
SyncWorker.cancelNext(this@App)
|
||||||
|
|
||||||
|
if (config.sync.notifyAboutUpdates)
|
||||||
|
UpdateWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
UpdateWorker.cancelNext(this@App)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||||
|
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
||||||
|
|
||||||
|
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
shortcutManager.dynamicShortcuts = listOf(
|
||||||
|
shortcutTimetable,
|
||||||
|
shortcutAgenda,
|
||||||
|
shortcutGrades,
|
||||||
|
shortcutHomework,
|
||||||
|
shortcutMessages
|
||||||
|
)
|
||||||
|
} // shortcuts - end
|
||||||
|
|
||||||
|
notificationChannelsManager.registerAllChannels()
|
||||||
|
|
||||||
|
|
||||||
|
if (config.appInstalledTime == 0L)
|
||||||
|
try {
|
||||||
|
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
||||||
|
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
val pushMobidziennikApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setProjectId("mobidziennik")
|
||||||
|
.setStorageBucket("mobidziennik.appspot.com")
|
||||||
|
.setDatabaseUrl("https://mobidziennik.firebaseio.com")
|
||||||
|
.setGcmSenderId("747285019373")
|
||||||
|
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
||||||
|
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
||||||
|
.build(),
|
||||||
|
"Mobidziennik2"
|
||||||
|
)
|
||||||
|
|
||||||
|
val pushLibrusApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setProjectId("synergiadru")
|
||||||
|
.setStorageBucket("synergiadru.appspot.com")
|
||||||
|
.setDatabaseUrl("https://synergiadru.firebaseio.com")
|
||||||
|
.setGcmSenderId("513056078587")
|
||||||
|
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
||||||
|
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
||||||
|
.build(),
|
||||||
|
"Librus"
|
||||||
|
)
|
||||||
|
|
||||||
|
val pushVulcanApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setProjectId("dzienniczekplus")
|
||||||
|
.setStorageBucket("dzienniczekplus.appspot.com")
|
||||||
|
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
|
||||||
|
.setGcmSenderId("987828170337")
|
||||||
|
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
||||||
|
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
||||||
|
.build(),
|
||||||
|
"Vulcan"
|
||||||
|
)
|
||||||
|
|
||||||
|
val pushVulcanHebeApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setProjectId("dzienniczekplus")
|
||||||
|
.setStorageBucket("dzienniczekplus.appspot.com")
|
||||||
|
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
|
||||||
|
.setGcmSenderId("987828170337")
|
||||||
|
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
||||||
|
.setApplicationId("1:987828170337:android:7e16404b9e5deaaa")
|
||||||
|
.build(),
|
||||||
|
"VulcanHebe"
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
d("Firebase", "Got App token: $token")
|
||||||
|
config.sync.tokenApp = token
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
d("Firebase", "Got Mobidziennik2 token: $token")
|
||||||
|
if (token != config.sync.tokenMobidziennik) {
|
||||||
|
config.sync.tokenMobidziennik = token
|
||||||
|
config.sync.tokenMobidziennikList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
d("Firebase", "Got Librus token: $token")
|
||||||
|
if (token != config.sync.tokenLibrus) {
|
||||||
|
config.sync.tokenLibrus = token
|
||||||
|
config.sync.tokenLibrusList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
d("Firebase", "Got Vulcan token: $token")
|
||||||
|
if (token != config.sync.tokenVulcan) {
|
||||||
|
config.sync.tokenVulcan = token
|
||||||
|
config.sync.tokenVulcanList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushVulcanHebeApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
d("Firebase", "Got VulcanHebe token: $token")
|
||||||
|
if (token != config.sync.tokenVulcanHebe) {
|
||||||
|
config.sync.tokenVulcanHebe = token
|
||||||
|
config.sync.tokenVulcanHebeList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db.metadataDao().countUnseen().observeForever { count: Int ->
|
db.metadataDao().countUnseen().observeForever { count: Int ->
|
||||||
if (unreadBadgesAvailable)
|
if (unreadBadgesAvailable)
|
||||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
|
||||||
|
|
||||||
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
shortcutManager.dynamicShortcuts = listOf(
|
|
||||||
shortcutTimetable,
|
|
||||||
shortcutAgenda,
|
|
||||||
shortcutGrades,
|
|
||||||
shortcutHomework,
|
|
||||||
shortcutMessages
|
|
||||||
)
|
|
||||||
} // shortcuts - end
|
|
||||||
|
|
||||||
if (config.appInstalledTime == 0L)
|
|
||||||
try {
|
|
||||||
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
|
||||||
config.appRateSnackbarTime = config.appInstalledTime + 7*DAY*MS
|
|
||||||
} catch (e: NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
val pushMobidziennikApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
|
||||||
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
|
||||||
.build(),
|
|
||||||
"Mobidziennik2"
|
|
||||||
)
|
|
||||||
|
|
||||||
val pushLibrusApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
|
||||||
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
|
||||||
.build(),
|
|
||||||
"Librus"
|
|
||||||
)
|
|
||||||
|
|
||||||
val pushVulcanApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
|
||||||
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
|
||||||
.build(),
|
|
||||||
"Vulcan"
|
|
||||||
)
|
|
||||||
|
|
||||||
try {
|
|
||||||
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
config.sync.tokenApp = token
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenMobidziennik) {
|
|
||||||
config.sync.tokenMobidziennik = token
|
|
||||||
config.sync.tokenMobidziennikList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenLibrus) {
|
|
||||||
config.sync.tokenLibrus = token
|
|
||||||
config.sync.tokenLibrusList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenVulcan) {
|
|
||||||
config.sync.tokenVulcan = token
|
|
||||||
config.sync.tokenVulcanList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
|
|
||||||
} catch (e: IllegalStateException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun profileLoad(profileId: Int) {
|
|
||||||
db.profileDao().getFullByIdNow(profileId)?.also {
|
|
||||||
profile = it
|
|
||||||
} ?: run {
|
|
||||||
if (!::profile.isInitialized) {
|
|
||||||
profile = ProfileFull(-1, "", "", -1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun profileLoad(profileId: Int, onSuccess: (profile: ProfileFull) -> Unit) {
|
|
||||||
|
private fun profileLoadById(profileId: Int): Boolean {
|
||||||
|
db.profileDao().getByIdNow(profileId)?.also {
|
||||||
|
App.profile = it
|
||||||
|
App.config.lastProfileId = it.id
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) {
|
||||||
launch {
|
launch {
|
||||||
val deferred = async(Dispatchers.Default) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
profileLoad(profileId)
|
profileLoadById(profileId)
|
||||||
}
|
}
|
||||||
deferred.await()
|
if (success)
|
||||||
onSuccess(profile)
|
onSuccess(profile)
|
||||||
|
else
|
||||||
|
profileLoadLast(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) {
|
||||||
private fun OkHttpClient.Builder.installHttpsSupport() {
|
launch {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
try {
|
profileLoadById(db.profileDao().lastId ?: return@withContext false)
|
||||||
try {
|
|
||||||
ProviderInstaller.installIfNeeded(this@App)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
|
||||||
|
|
||||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
|
||||||
trustManagerFactory.init(null as KeyStore?)
|
|
||||||
|
|
||||||
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
|
||||||
?: return
|
|
||||||
|
|
||||||
val sc = SSLContext.getInstance("TLSv1.2")
|
|
||||||
sc.init(null, null, null)
|
|
||||||
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
|
||||||
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_0)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_1)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_2)
|
|
||||||
.build()
|
|
||||||
val specs: MutableList<ConnectionSpec> = ArrayList()
|
|
||||||
specs.add(cs)
|
|
||||||
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
|
||||||
specs.add(ConnectionSpec.CLEARTEXT)
|
|
||||||
connectionSpecs(specs)
|
|
||||||
}
|
|
||||||
} catch (exc: Exception) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
|
||||||
}
|
}
|
||||||
|
if (!success) {
|
||||||
|
EventBus.getDefault().post(ProfileListEmptyEvent())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
onSuccess(profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun profileSave() = profileSave(profile)
|
||||||
|
fun profileSave(profile: Profile) {
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
App.db.profileDao().add(profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,5 +404,5 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-11-11.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.databinding.BindingAdapter;
|
|
||||||
|
|
||||||
public class Binding {
|
|
||||||
@BindingAdapter("strikeThrough")
|
|
||||||
public static void strikeThrough(TextView textView, Boolean strikeThrough) {
|
|
||||||
if (strikeThrough) {
|
|
||||||
textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
} else {
|
|
||||||
textView.setPaintFlags(textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
20
app/src/main/java/pl/szczodrzynski/edziennik/Binding.kt
Normal file
20
app/src/main/java/pl/szczodrzynski/edziennik/Binding.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-11-11.
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.databinding.BindingAdapter
|
||||||
|
|
||||||
|
object Binding {
|
||||||
|
@JvmStatic
|
||||||
|
@BindingAdapter("strikeThrough")
|
||||||
|
fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
|
||||||
|
if (strikeThrough) {
|
||||||
|
textView.paintFlags = textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
|
} else {
|
||||||
|
textView.paintFlags = textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,17 @@ package pl.szczodrzynski.edziennik
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.graphics.PorterDuffColorFilter
|
import android.graphics.PorterDuffColorFilter
|
||||||
|
import android.graphics.Rect
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -22,9 +26,8 @@ import android.util.Base64
|
|||||||
import android.util.Base64.NO_WRAP
|
import android.util.Base64.NO_WRAP
|
||||||
import android.util.Base64.encodeToString
|
import android.util.Base64.encodeToString
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.CheckBox
|
import android.view.WindowManager
|
||||||
import android.widget.CompoundButton
|
import android.widget.*
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.*
|
import androidx.annotation.*
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.database.getIntOrNull
|
import androidx.core.database.getIntOrNull
|
||||||
@ -34,30 +37,53 @@ import androidx.core.util.forEach
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import androidx.viewpager.widget.ViewPager
|
||||||
|
import com.google.android.gms.security.ProviderInstaller
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.google.gson.*
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.TlsVersion
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApiException
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
||||||
|
import pl.szczodrzynski.edziennik.network.TLSSocketFactory
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import java.io.InterruptedIOException
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
import java.net.ConnectException
|
||||||
|
import java.net.SocketTimeoutException
|
||||||
|
import java.net.UnknownHostException
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
import java.security.KeyStore
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.CRC32
|
import java.util.zip.CRC32
|
||||||
import javax.crypto.Mac
|
import javax.crypto.Mac
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
import javax.net.ssl.SSLContext
|
||||||
|
import javax.net.ssl.SSLException
|
||||||
|
import javax.net.ssl.TrustManagerFactory
|
||||||
|
import javax.net.ssl.X509TrustManager
|
||||||
import kotlin.Pair
|
import kotlin.Pair
|
||||||
|
|
||||||
|
|
||||||
@ -69,23 +95,34 @@ fun List<Teacher>.byNameFDotSpaceLast(nameFDotSpaceLast: String) = firstOrNull {
|
|||||||
|
|
||||||
fun JsonObject?.get(key: String): JsonElement? = this?.get(key)
|
fun JsonObject?.get(key: String): JsonElement? = this?.get(key)
|
||||||
|
|
||||||
fun JsonObject?.getBoolean(key: String): Boolean? = get(key)?.let { if (it.isJsonNull) null else it.asBoolean }
|
fun JsonObject?.getBoolean(key: String): Boolean? = get(key)?.let { if (!it.isJsonPrimitive) null else it.asBoolean }
|
||||||
fun JsonObject?.getString(key: String): String? = get(key)?.let { if (it.isJsonNull) null else it.asString }
|
fun JsonObject?.getString(key: String): String? = get(key)?.let { if (!it.isJsonPrimitive) null else it.asString }
|
||||||
fun JsonObject?.getInt(key: String): Int? = get(key)?.let { if (it.isJsonNull) null else it.asInt }
|
fun JsonObject?.getInt(key: String): Int? = get(key)?.let { if (!it.isJsonPrimitive) null else it.asInt }
|
||||||
fun JsonObject?.getLong(key: String): Long? = get(key)?.let { if (it.isJsonNull) null else it.asLong }
|
fun JsonObject?.getLong(key: String): Long? = get(key)?.let { if (!it.isJsonPrimitive) null else it.asLong }
|
||||||
fun JsonObject?.getFloat(key: String): Float? = get(key)?.let { if(it.isJsonNull) null else it.asFloat }
|
fun JsonObject?.getFloat(key: String): Float? = get(key)?.let { if(!it.isJsonPrimitive) null else it.asFloat }
|
||||||
fun JsonObject?.getChar(key: String): Char? = get(key)?.let { if(it.isJsonNull) null else it.asCharacter }
|
fun JsonObject?.getChar(key: String): Char? = get(key)?.let { if(!it.isJsonPrimitive) null else it.asCharacter }
|
||||||
fun JsonObject?.getJsonObject(key: String): JsonObject? = get(key)?.let { if (it.isJsonNull) null else it.asJsonObject }
|
fun JsonObject?.getJsonObject(key: String): JsonObject? = get(key)?.let { if (it.isJsonObject) it.asJsonObject else null }
|
||||||
fun JsonObject?.getJsonArray(key: String): JsonArray? = get(key)?.let { if (it.isJsonNull) null else it.asJsonArray }
|
fun JsonObject?.getJsonArray(key: String): JsonArray? = get(key)?.let { if (it.isJsonArray) it.asJsonArray else null }
|
||||||
|
|
||||||
fun JsonObject?.getBoolean(key: String, defaultValue: Boolean): Boolean = get(key)?.let { if (it.isJsonNull) defaultValue else it.asBoolean } ?: defaultValue
|
fun JsonObject?.getBoolean(key: String, defaultValue: Boolean): Boolean = get(key)?.let { if (!it.isJsonPrimitive) defaultValue else it.asBoolean } ?: defaultValue
|
||||||
fun JsonObject?.getString(key: String, defaultValue: String): String = get(key)?.let { if (it.isJsonNull) defaultValue else it.asString } ?: defaultValue
|
fun JsonObject?.getString(key: String, defaultValue: String): String = get(key)?.let { if (!it.isJsonPrimitive) defaultValue else it.asString } ?: defaultValue
|
||||||
fun JsonObject?.getInt(key: String, defaultValue: Int): Int = get(key)?.let { if (it.isJsonNull) defaultValue else it.asInt } ?: defaultValue
|
fun JsonObject?.getInt(key: String, defaultValue: Int): Int = get(key)?.let { if (!it.isJsonPrimitive) defaultValue else it.asInt } ?: defaultValue
|
||||||
fun JsonObject?.getLong(key: String, defaultValue: Long): Long = get(key)?.let { if (it.isJsonNull) defaultValue else it.asLong } ?: defaultValue
|
fun JsonObject?.getLong(key: String, defaultValue: Long): Long = get(key)?.let { if (!it.isJsonPrimitive) defaultValue else it.asLong } ?: defaultValue
|
||||||
fun JsonObject?.getFloat(key: String, defaultValue: Float): Float = get(key)?.let { if(it.isJsonNull) defaultValue else it.asFloat } ?: defaultValue
|
fun JsonObject?.getFloat(key: String, defaultValue: Float): Float = get(key)?.let { if(!it.isJsonPrimitive) defaultValue else it.asFloat } ?: defaultValue
|
||||||
fun JsonObject?.getChar(key: String, defaultValue: Char): Char = get(key)?.let { if(it.isJsonNull) defaultValue else it.asCharacter } ?: defaultValue
|
fun JsonObject?.getChar(key: String, defaultValue: Char): Char = get(key)?.let { if(!it.isJsonPrimitive) defaultValue else it.asCharacter } ?: defaultValue
|
||||||
fun JsonObject?.getJsonObject(key: String, defaultValue: JsonObject): JsonObject = get(key)?.let { if (it.isJsonNull) defaultValue else it.asJsonObject } ?: defaultValue
|
fun JsonObject?.getJsonObject(key: String, defaultValue: JsonObject): JsonObject = get(key)?.let { if (it.isJsonObject) it.asJsonObject else defaultValue } ?: defaultValue
|
||||||
fun JsonObject?.getJsonArray(key: String, defaultValue: JsonArray): JsonArray = get(key)?.let { if (it.isJsonNull) defaultValue else it.asJsonArray } ?: defaultValue
|
fun JsonObject?.getJsonArray(key: String, defaultValue: JsonArray): JsonArray = get(key)?.let { if (it.isJsonArray) it.asJsonArray else defaultValue } ?: defaultValue
|
||||||
|
|
||||||
|
fun JsonArray.getBoolean(key: Int): Boolean? = if (key >= size()) null else get(key)?.let { if (!it.isJsonPrimitive) null else it.asBoolean }
|
||||||
|
fun JsonArray.getString(key: Int): String? = if (key >= size()) null else get(key)?.let { if (!it.isJsonPrimitive) null else it.asString }
|
||||||
|
fun JsonArray.getInt(key: Int): Int? = if (key >= size()) null else get(key)?.let { if (!it.isJsonPrimitive) null else it.asInt }
|
||||||
|
fun JsonArray.getLong(key: Int): Long? = if (key >= size()) null else get(key)?.let { if (!it.isJsonPrimitive) null else it.asLong }
|
||||||
|
fun JsonArray.getFloat(key: Int): Float? = if (key >= size()) null else get(key)?.let { if(!it.isJsonPrimitive) null else it.asFloat }
|
||||||
|
fun JsonArray.getChar(key: Int): Char? = if (key >= size()) null else get(key)?.let { if(!it.isJsonPrimitive) null else it.asCharacter }
|
||||||
|
fun JsonArray.getJsonObject(key: Int): JsonObject? = if (key >= size()) null else get(key)?.let { if (it.isJsonObject) it.asJsonObject else null }
|
||||||
|
fun JsonArray.getJsonArray(key: Int): JsonArray? = if (key >= size()) null else get(key)?.let { if (it.isJsonArray) it.asJsonArray else null }
|
||||||
|
|
||||||
|
fun String.toJsonObject(): JsonObject? = try { JsonParser().parse(this).asJsonObject } catch (ignore: Exception) { null }
|
||||||
|
|
||||||
operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value)
|
operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value)
|
||||||
operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value)
|
operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value)
|
||||||
@ -105,6 +142,14 @@ fun CharSequence?.isNotNullNorEmpty(): Boolean {
|
|||||||
return this != null && this.isNotEmpty()
|
return this != null && this.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> Collection<T>?.isNotNullNorEmpty(): Boolean {
|
||||||
|
return this != null && this.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CharSequence?.isNotNullNorBlank(): Boolean {
|
||||||
|
return this != null && this.isNotBlank()
|
||||||
|
}
|
||||||
|
|
||||||
fun currentTimeUnix() = System.currentTimeMillis() / 1000
|
fun currentTimeUnix() = System.currentTimeMillis() / 1000
|
||||||
|
|
||||||
fun Bundle?.getInt(key: String, defaultValue: Int): Int {
|
fun Bundle?.getInt(key: String, defaultValue: Int): Int {
|
||||||
@ -120,6 +165,13 @@ fun Bundle?.getString(key: String, defaultValue: String): String {
|
|||||||
return this?.getString(key, defaultValue) ?: defaultValue
|
return this?.getString(key, defaultValue) ?: defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Bundle?.getIntOrNull(key: String): Int? {
|
||||||
|
return this?.get(key) as? Int
|
||||||
|
}
|
||||||
|
fun <T : Any> Bundle?.get(key: String): T? {
|
||||||
|
return this?.get(key) as? T?
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ` The quick BROWN_fox Jumps OveR THE LAZy-DOG. `
|
* ` The quick BROWN_fox Jumps OveR THE LAZy-DOG. `
|
||||||
*
|
*
|
||||||
@ -246,7 +298,7 @@ fun colorFromCssName(name: String): Int {
|
|||||||
"orange" -> 0xffffa500
|
"orange" -> 0xffffa500
|
||||||
"black" -> 0xff000000
|
"black" -> 0xff000000
|
||||||
"white" -> 0xffffffff
|
"white" -> 0xffffffff
|
||||||
else -> -1
|
else -> -1L
|
||||||
}.toInt()
|
}.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +454,7 @@ operator fun MatchResult.get(group: Int): String {
|
|||||||
return groupValues[group]
|
return groupValues[group]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.setLanguage(language: String) {
|
fun Context.setLanguage(language: String) {
|
||||||
val locale = Locale(language.toLowerCase(Locale.ROOT))
|
val locale = Locale(language.toLowerCase(Locale.ROOT))
|
||||||
val configuration = resources.configuration
|
val configuration = resources.configuration
|
||||||
Locale.setDefault(locale)
|
Locale.setDefault(locale)
|
||||||
@ -411,7 +463,6 @@ fun Activity.setLanguage(language: String) {
|
|||||||
}
|
}
|
||||||
configuration.locale = locale
|
configuration.locale = locale
|
||||||
resources.updateConfiguration(configuration, resources.displayMetrics)
|
resources.updateConfiguration(configuration, resources.displayMetrics)
|
||||||
baseContext.resources.updateConfiguration(configuration, baseContext.resources.displayMetrics)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -486,6 +537,12 @@ fun String.md5(): String {
|
|||||||
return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
|
return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.sha1Hex(): String {
|
||||||
|
val md = MessageDigest.getInstance("SHA-1")
|
||||||
|
md.update(toByteArray())
|
||||||
|
return md.digest().joinToString("") { "%02x".format(it) }
|
||||||
|
}
|
||||||
|
|
||||||
fun String.sha256(): ByteArray {
|
fun String.sha256(): ByteArray {
|
||||||
val md = MessageDigest.getInstance("SHA-256")
|
val md = MessageDigest.getInstance("SHA-256")
|
||||||
md.update(toByteArray())
|
md.update(toByteArray())
|
||||||
@ -520,7 +577,7 @@ fun CharSequence?.asBoldSpannable(): Spannable {
|
|||||||
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignoreCase: Boolean = false): Spannable {
|
fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignoreCase: Boolean = false, ignoreDiacritics: Boolean = false): Spannable {
|
||||||
val spannable = SpannableString(this)
|
val spannable = SpannableString(this)
|
||||||
if (substring == null) {
|
if (substring == null) {
|
||||||
spans.forEach {
|
spans.forEach {
|
||||||
@ -528,17 +585,44 @@ fun CharSequence.asSpannable(vararg spans: Any, substring: String? = null, ignor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (substring.isNotEmpty()) {
|
else if (substring.isNotEmpty()) {
|
||||||
var index = indexOf(substring, ignoreCase = ignoreCase)
|
val string =
|
||||||
|
if (ignoreDiacritics)
|
||||||
|
this.cleanDiacritics()
|
||||||
|
else this
|
||||||
|
|
||||||
|
var index = string.indexOf(substring, ignoreCase = ignoreCase)
|
||||||
|
.takeIf { it != -1 } ?: indexOf(substring, ignoreCase = ignoreCase)
|
||||||
while (index >= 0) {
|
while (index >= 0) {
|
||||||
spans.forEach {
|
spans.forEach {
|
||||||
spannable.setSpan(it, index, index + substring.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(it, index, index + substring.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
index = indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
index = string.indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
||||||
|
.takeIf { it != -1 } ?: indexOf(substring, startIndex = index + 1, ignoreCase = ignoreCase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun CharSequence.cleanDiacritics(): String {
|
||||||
|
val nameClean = StringBuilder()
|
||||||
|
forEach {
|
||||||
|
val ch = when (it) {
|
||||||
|
'ż' -> 'z'
|
||||||
|
'ó' -> 'o'
|
||||||
|
'ł' -> 'l'
|
||||||
|
'ć' -> 'c'
|
||||||
|
'ę' -> 'e'
|
||||||
|
'ś' -> 's'
|
||||||
|
'ą' -> 'a'
|
||||||
|
'ź' -> 'z'
|
||||||
|
'ń' -> 'n'
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
nameClean.append(ch)
|
||||||
|
}
|
||||||
|
return nameClean.toString()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new read-only list only of those given elements, that are not empty.
|
* Returns a new read-only list only of those given elements, that are not empty.
|
||||||
* Applies for CharSequence and descendants.
|
* Applies for CharSequence and descendants.
|
||||||
@ -594,6 +678,16 @@ fun TextView.setText(@StringRes resid: Int, vararg formatArgs: Any) {
|
|||||||
text = context.getString(resid, *formatArgs)
|
text = context.getString(resid, *formatArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MaterialAlertDialogBuilder.setTitle(@StringRes resid: Int, vararg formatArgs: Any): MaterialAlertDialogBuilder {
|
||||||
|
setTitle(context.getString(resid, *formatArgs))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MaterialAlertDialogBuilder.setMessage(@StringRes resid: Int, vararg formatArgs: Any): MaterialAlertDialogBuilder {
|
||||||
|
setMessage(context.getString(resid, *formatArgs))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
|
fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
|
||||||
return JsonObject().apply {
|
return JsonObject().apply {
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
@ -608,6 +702,21 @@ fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JsonObject.toBundle(): Bundle {
|
||||||
|
return Bundle().also {
|
||||||
|
for ((key, value) in this.entrySet()) {
|
||||||
|
when (value) {
|
||||||
|
is JsonObject -> it.putBundle(key, value.toBundle())
|
||||||
|
is JsonPrimitive -> when {
|
||||||
|
value.isString -> it.putString(key, value.asString)
|
||||||
|
value.isBoolean -> it.putBoolean(key, value.asBoolean)
|
||||||
|
value.isNumber -> it.putInt(key, value.asInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun JsonArray(vararg properties: Any?): JsonArray {
|
fun JsonArray(vararg properties: Any?): JsonArray {
|
||||||
return JsonArray().apply {
|
return JsonArray().apply {
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
@ -638,6 +747,34 @@ fun Bundle(vararg properties: Pair<String, Any?>): Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun Intent(action: String? = null, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(action).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
fun Intent(packageContext: Context, cls: Class<*>, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(packageContext, cls).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Bundle.toJsonObject(): JsonObject {
|
||||||
|
val json = JsonObject()
|
||||||
|
keySet()?.forEach { key ->
|
||||||
|
get(key)?.let {
|
||||||
|
when (it) {
|
||||||
|
is String -> json.addProperty(key, it)
|
||||||
|
is Char -> json.addProperty(key, it)
|
||||||
|
is Int -> json.addProperty(key, it)
|
||||||
|
is Long -> json.addProperty(key, it)
|
||||||
|
is Float -> json.addProperty(key, it)
|
||||||
|
is Short -> json.addProperty(key, it)
|
||||||
|
is Double -> json.addProperty(key, it)
|
||||||
|
is Boolean -> json.addProperty(key, it)
|
||||||
|
is Bundle -> json.add(key, it.toJsonObject())
|
||||||
|
else -> json.addProperty(key, it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
fun Intent.toJsonObject() = extras?.toJsonObject()
|
||||||
|
|
||||||
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
||||||
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
||||||
@ -654,6 +791,13 @@ inline fun <T : View> T.onClick(crossinline onClickListener: (v: T) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : View> T.onLongClick(crossinline onLongClickListener: (v: T) -> Boolean) {
|
||||||
|
setOnLongClickListener { v: View ->
|
||||||
|
onLongClickListener(v as T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
||||||
setOnCheckedChangeListener { buttonView, isChecked ->
|
setOnCheckedChangeListener { buttonView, isChecked ->
|
||||||
@ -661,6 +805,19 @@ inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : MaterialButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
|
||||||
|
clearOnCheckedChangeListeners()
|
||||||
|
addOnCheckedChangeListener { buttonView, isChecked ->
|
||||||
|
onChangeListener(buttonView as T, isChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun View.attachToastHint(stringRes: Int) = onLongClick {
|
||||||
|
Toast.makeText(it.context, stringRes, Toast.LENGTH_SHORT).show()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
|
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
|
||||||
observe(lifecycleOwner, object : Observer<T> {
|
observe(lifecycleOwner, object : Observer<T> {
|
||||||
override fun onChanged(t: T?) {
|
override fun onChanged(t: T?) {
|
||||||
@ -716,7 +873,7 @@ fun View.findParentById(targetId: Int): View? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = launch {
|
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: suspend CoroutineScope.() -> Unit) = launch {
|
||||||
delay(delayMillis)
|
delay(delayMillis)
|
||||||
if (repeatMillis > 0) {
|
if (repeatMillis > 0) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -930,6 +1087,8 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
||||||
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
||||||
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
||||||
|
Notification.TYPE_NEW_SHARED_HOMEWORK -> R.string.notification_type_new_shared_homework
|
||||||
|
Notification.TYPE_REMOVED_SHARED_EVENT -> R.string.notification_type_removed_shared_event
|
||||||
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
||||||
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
||||||
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
||||||
@ -938,6 +1097,7 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
Notification.TYPE_FEEDBACK_MESSAGE -> R.string.notification_type_feedback_message
|
Notification.TYPE_FEEDBACK_MESSAGE -> R.string.notification_type_feedback_message
|
||||||
Notification.TYPE_NEW_ANNOUNCEMENT -> R.string.notification_type_new_announcement
|
Notification.TYPE_NEW_ANNOUNCEMENT -> R.string.notification_type_new_announcement
|
||||||
Notification.TYPE_AUTO_ARCHIVING -> R.string.notification_type_auto_archiving
|
Notification.TYPE_AUTO_ARCHIVING -> R.string.notification_type_auto_archiving
|
||||||
|
Notification.TYPE_TEACHER_ABSENCE -> R.string.notification_type_new_teacher_absence
|
||||||
Notification.TYPE_GENERAL -> R.string.notification_type_general
|
Notification.TYPE_GENERAL -> R.string.notification_type_general
|
||||||
else -> R.string.notification_type_general
|
else -> R.string.notification_type_general
|
||||||
})
|
})
|
||||||
@ -946,3 +1106,175 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.installHttpsSupport(context: Context) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
ProviderInstaller.installIfNeeded(context)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
||||||
|
|
||||||
|
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||||
|
trustManagerFactory.init(null as KeyStore?)
|
||||||
|
|
||||||
|
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
||||||
|
?: return
|
||||||
|
|
||||||
|
val sc = SSLContext.getInstance("TLSv1.2")
|
||||||
|
sc.init(null, null, null)
|
||||||
|
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
||||||
|
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_0)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_1)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_2)
|
||||||
|
.build()
|
||||||
|
val specs: MutableList<ConnectionSpec> = ArrayList()
|
||||||
|
specs.add(cs)
|
||||||
|
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
||||||
|
specs.add(ConnectionSpec.CLEARTEXT)
|
||||||
|
connectionSpecs(specs)
|
||||||
|
}
|
||||||
|
} catch (exc: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CharSequence.containsAll(list: List<CharSequence>, ignoreCase: Boolean = false): Boolean {
|
||||||
|
for (i in list) {
|
||||||
|
if (!contains(i, ignoreCase))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun RadioButton.setOnSelectedListener(crossinline listener: (buttonView: CompoundButton) -> Unit)
|
||||||
|
= setOnCheckedChangeListener { buttonView, isChecked -> if (isChecked) listener(buttonView) }
|
||||||
|
|
||||||
|
fun Response.toErrorCode() = when (this.code()) {
|
||||||
|
400 -> ERROR_REQUEST_HTTP_400
|
||||||
|
401 -> ERROR_REQUEST_HTTP_401
|
||||||
|
403 -> ERROR_REQUEST_HTTP_403
|
||||||
|
404 -> ERROR_REQUEST_HTTP_404
|
||||||
|
405 -> ERROR_REQUEST_HTTP_405
|
||||||
|
410 -> ERROR_REQUEST_HTTP_410
|
||||||
|
424 -> ERROR_REQUEST_HTTP_424
|
||||||
|
500 -> ERROR_REQUEST_HTTP_500
|
||||||
|
503 -> ERROR_REQUEST_HTTP_503
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
fun Throwable.toErrorCode() = when (this) {
|
||||||
|
is UnknownHostException -> ERROR_REQUEST_FAILURE_HOSTNAME_NOT_FOUND
|
||||||
|
is SSLException -> ERROR_REQUEST_FAILURE_SSL_ERROR
|
||||||
|
is SocketTimeoutException -> ERROR_REQUEST_FAILURE_TIMEOUT
|
||||||
|
is InterruptedIOException, is ConnectException -> ERROR_REQUEST_FAILURE_NO_INTERNET
|
||||||
|
is SzkolnyApiException -> this.error?.toErrorCode()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
private fun ApiResponse.Error.toErrorCode() = when (this.code) {
|
||||||
|
else -> ERROR_API_EXCEPTION
|
||||||
|
}
|
||||||
|
fun Throwable.toApiError(tag: String) = ApiError.fromThrowable(tag, this)
|
||||||
|
|
||||||
|
inline fun <A, B, R> ifNotNull(a: A?, b: B?, code: (A, B) -> R): R? {
|
||||||
|
if (a != null && b != null) {
|
||||||
|
return code(a, b)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmName("averageOrNullOfInt")
|
||||||
|
fun Iterable<Int>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||||
|
@kotlin.jvm.JvmName("averageOrNullOfFloat")
|
||||||
|
fun Iterable<Float>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||||
|
|
||||||
|
fun String.copyToClipboard(context: Context) {
|
||||||
|
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clipData = ClipData.newPlainText("Tekst", this)
|
||||||
|
clipboard.setPrimaryClip(clipData)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TextView.getTextPosition(range: IntRange): Rect {
|
||||||
|
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
|
|
||||||
|
// Initialize global value
|
||||||
|
var parentTextViewRect = Rect()
|
||||||
|
|
||||||
|
// Initialize values for the computing of clickedText position
|
||||||
|
//val completeText = parentTextView.text as SpannableString
|
||||||
|
val textViewLayout = this.layout
|
||||||
|
|
||||||
|
val startOffsetOfClickedText = range.first//completeText.getSpanStart(clickedText)
|
||||||
|
val endOffsetOfClickedText = range.last//completeText.getSpanEnd(clickedText)
|
||||||
|
var startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(startOffsetOfClickedText)
|
||||||
|
var endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(endOffsetOfClickedText)
|
||||||
|
|
||||||
|
// Get the rectangle of the clicked text
|
||||||
|
val currentLineStartOffset = textViewLayout.getLineForOffset(startOffsetOfClickedText)
|
||||||
|
val currentLineEndOffset = textViewLayout.getLineForOffset(endOffsetOfClickedText)
|
||||||
|
val keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset
|
||||||
|
textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect)
|
||||||
|
|
||||||
|
// Update the rectangle position to his real position on screen
|
||||||
|
val parentTextViewLocation = intArrayOf(0, 0)
|
||||||
|
this.getLocationOnScreen(parentTextViewLocation)
|
||||||
|
|
||||||
|
val parentTextViewTopAndBottomOffset = (parentTextViewLocation[1] - this.scrollY + this.compoundPaddingTop)
|
||||||
|
parentTextViewRect.top += parentTextViewTopAndBottomOffset
|
||||||
|
parentTextViewRect.bottom += parentTextViewTopAndBottomOffset
|
||||||
|
|
||||||
|
// In the case of multi line text, we have to choose what rectangle take
|
||||||
|
if (keywordIsInMultiLine) {
|
||||||
|
val screenHeight = windowManager.defaultDisplay.height
|
||||||
|
val dyTop = parentTextViewRect.top
|
||||||
|
val dyBottom = screenHeight - parentTextViewRect.bottom
|
||||||
|
val onTop = dyTop > dyBottom
|
||||||
|
|
||||||
|
if (onTop) {
|
||||||
|
endXCoordinatesOfClickedText = textViewLayout.getLineRight(currentLineStartOffset);
|
||||||
|
} else {
|
||||||
|
parentTextViewRect = Rect()
|
||||||
|
textViewLayout.getLineBounds(currentLineEndOffset, parentTextViewRect);
|
||||||
|
parentTextViewRect.top += parentTextViewTopAndBottomOffset;
|
||||||
|
parentTextViewRect.bottom += parentTextViewTopAndBottomOffset;
|
||||||
|
startXCoordinatesOfClickedText = textViewLayout.getLineLeft(currentLineEndOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parentTextViewRect.left += (
|
||||||
|
parentTextViewLocation[0] +
|
||||||
|
startXCoordinatesOfClickedText +
|
||||||
|
this.compoundPaddingLeft -
|
||||||
|
this.scrollX
|
||||||
|
).toInt()
|
||||||
|
parentTextViewRect.right = (
|
||||||
|
parentTextViewRect.left +
|
||||||
|
endXCoordinatesOfClickedText -
|
||||||
|
startXCoordinatesOfClickedText
|
||||||
|
).toInt()
|
||||||
|
|
||||||
|
return parentTextViewRect
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun ViewPager.addOnPageSelectedListener(crossinline block: (position: Int) -> Unit) = addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||||
|
override fun onPageScrollStateChanged(state: Int) {}
|
||||||
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||||
|
override fun onPageSelected(position: Int) { block(position) }
|
||||||
|
})
|
||||||
|
|
||||||
|
val SwipeRefreshLayout.onScrollListener: RecyclerView.OnScrollListener
|
||||||
|
get() = object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
|
if (recyclerView.canScrollVertically(-1))
|
||||||
|
this@onScrollListener.isEnabled = false
|
||||||
|
if (!recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE)
|
||||||
|
this@onScrollListener.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun <K, V> Iterable<Pair<K, V>>.get(key: K): V? {
|
||||||
|
return firstOrNull { it.first == key }?.second
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -9,21 +8,19 @@ import android.content.IntentFilter
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.danimahardhika.cafebar.CafeBar
|
import com.danimahardhika.cafebar.CafeBar
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.mikepenz.iconics.IconicsColor
|
import com.mikepenz.iconics.IconicsColor
|
||||||
@ -34,42 +31,53 @@ import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
|||||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
import com.mikepenz.materialdrawer.model.utils.withIsHiddenInMiniDrawer
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.droidsonroids.gif.GifDrawable
|
import pl.droidsonroids.gif.GifDrawable
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_API_DEPRECATED
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
||||||
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.RegisterUnavailableDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.ServerMessageDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.UpdateAvailableDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.DebugFragment
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.MainSnackbar
|
import pl.szczodrzynski.edziennik.ui.modules.base.MainSnackbar
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment
|
import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.DebugFragment
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.LabFragment
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorDetailsDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
|
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
|
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
|
import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesListFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeFragment
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.compose.MessagesComposeFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsListFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment
|
import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
||||||
@ -89,13 +97,13 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
|||||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||||
import pl.szczodrzynski.navlib.drawer.items.withAppTitle
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
var useOldMessages = false
|
var useOldMessages = false
|
||||||
@ -108,6 +116,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
const val DRAWER_PROFILE_SYNC_ALL = 201
|
const val DRAWER_PROFILE_SYNC_ALL = 201
|
||||||
const val DRAWER_PROFILE_EXPORT_DATA = 202
|
const val DRAWER_PROFILE_EXPORT_DATA = 202
|
||||||
const val DRAWER_PROFILE_MANAGE = 203
|
const val DRAWER_PROFILE_MANAGE = 203
|
||||||
|
const val DRAWER_PROFILE_MARK_ALL_AS_READ = 204
|
||||||
const val DRAWER_ITEM_HOME = 1
|
const val DRAWER_ITEM_HOME = 1
|
||||||
const val DRAWER_ITEM_TIMETABLE = 11
|
const val DRAWER_ITEM_TIMETABLE = 11
|
||||||
const val DRAWER_ITEM_AGENDA = 12
|
const val DRAWER_ITEM_AGENDA = 12
|
||||||
@ -127,6 +136,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
const val TARGET_MESSAGES_DETAILS = 503
|
const val TARGET_MESSAGES_DETAILS = 503
|
||||||
const val TARGET_MESSAGES_COMPOSE = 504
|
const val TARGET_MESSAGES_COMPOSE = 504
|
||||||
const val TARGET_WEB_PUSH = 140
|
const val TARGET_WEB_PUSH = 140
|
||||||
|
const val TARGET_LAB = 1000
|
||||||
|
|
||||||
const val HOME_ID = DRAWER_ITEM_HOME
|
const val HOME_ID = DRAWER_ITEM_HOME
|
||||||
|
|
||||||
@ -151,7 +161,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
.withBadgeTypeId(TYPE_EVENT)
|
.withBadgeTypeId(TYPE_EVENT)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
|
|
||||||
list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesFragment::class)
|
list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesListFragment::class)
|
||||||
.withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box_outline)
|
.withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box_outline)
|
||||||
.withBadgeTypeId(TYPE_GRADE)
|
.withBadgeTypeId(TYPE_GRADE)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
@ -183,7 +193,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
|
|
||||||
// static drawer items
|
// static drawer items
|
||||||
list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsFragment::class)
|
list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsListFragment::class)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_bell_ring_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_bell_ring_outline)
|
||||||
.isInDrawer(true)
|
.isInDrawer(true)
|
||||||
.isStatic(true)
|
.isStatic(true)
|
||||||
@ -208,6 +218,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
.withDescription(R.string.drawer_manage_profiles_desc)
|
.withDescription(R.string.drawer_manage_profiles_desc)
|
||||||
.isInProfileList(false)
|
.isInProfileList(false)
|
||||||
|
|
||||||
|
list += NavTarget(DRAWER_PROFILE_MARK_ALL_AS_READ, R.string.menu_mark_everything_as_read, null)
|
||||||
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
|
.isInProfileList(true)
|
||||||
|
|
||||||
list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null)
|
list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
||||||
.isInProfileList(true)
|
.isInProfileList(true)
|
||||||
@ -220,12 +234,23 @@ class MainActivity : AppCompatActivity() {
|
|||||||
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
|
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
|
||||||
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class)
|
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class)
|
||||||
list += NavTarget(TARGET_WEB_PUSH, R.string.menu_web_push, WebPushFragment::class)
|
list += NavTarget(TARGET_WEB_PUSH, R.string.menu_web_push, WebPushFragment::class)
|
||||||
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
if (App.devMode) {
|
||||||
|
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
||||||
|
list += NavTarget(TARGET_LAB, R.string.menu_lab, LabFragment::class)
|
||||||
|
.withIcon(CommunityMaterial.Icon.cmd_flask_outline)
|
||||||
|
.isInDrawer(true)
|
||||||
|
.isBelowSeparator(true)
|
||||||
|
.isStatic(true)
|
||||||
|
}
|
||||||
|
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
val b: ActivitySzkolnyBinding by lazy { ActivitySzkolnyBinding.inflate(layoutInflater) }
|
val b: ActivitySzkolnyBinding by lazy { ActivitySzkolnyBinding.inflate(layoutInflater) }
|
||||||
val navView: NavView by lazy { b.navView }
|
val navView: NavView by lazy { b.navView }
|
||||||
val drawer: NavDrawer by lazy { navView.drawer }
|
val drawer: NavDrawer by lazy { navView.drawer }
|
||||||
@ -257,19 +282,42 @@ class MainActivity : AppCompatActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
d(TAG, "Activity created")
|
||||||
|
|
||||||
setTheme(Themes.appTheme)
|
setTheme(Themes.appTheme)
|
||||||
|
|
||||||
app.config.ui.language?.let {
|
app.config.ui.language?.let {
|
||||||
setLanguage(it)
|
setLanguage(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentView(b.root)
|
if (App.profileId == 0) {
|
||||||
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(TAG, Signing.appPassword)
|
d(TAG, "Profile is valid, inflating views")
|
||||||
|
|
||||||
|
setContentView(b.root)
|
||||||
|
|
||||||
mainSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
mainSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
||||||
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
||||||
|
|
||||||
|
when {
|
||||||
|
BuildConfig.VERSION_NAME.contains("nightly") -> {
|
||||||
|
b.nightlyText.isVisible = true
|
||||||
|
b.nightlyText.text = "Nightly\n"+BuildConfig.VERSION_NAME.substringAfterLast(".")
|
||||||
|
}
|
||||||
|
BuildConfig.VERSION_NAME.contains("daily") -> {
|
||||||
|
b.nightlyText.isVisible = true
|
||||||
|
b.nightlyText.text = "Daily\n"+BuildConfig.VERSION_NAME.substringAfterLast(".")
|
||||||
|
}
|
||||||
|
BuildConfig.DEBUG -> {
|
||||||
|
b.nightlyText.isVisible = true
|
||||||
|
b.nightlyText.text = "Debug\n"+BuildConfig.VERSION_NAME
|
||||||
|
}
|
||||||
|
else -> b.nightlyText.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
navLoading = true
|
navLoading = true
|
||||||
|
|
||||||
b.navView.apply {
|
b.navView.apply {
|
||||||
@ -332,8 +380,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
setAccountHeaderBackground(app.config.ui.headerBackground)
|
setAccountHeaderBackground(app.config.ui.headerBackground)
|
||||||
|
|
||||||
drawerProfileListEmptyListener = {
|
drawerProfileListEmptyListener = {
|
||||||
app.config.loginFinished = false
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
profileListEmptyListener()
|
|
||||||
}
|
}
|
||||||
drawerItemSelectedListener = { id, position, drawerItem ->
|
drawerItemSelectedListener = { id, position, drawerItem ->
|
||||||
loadTarget(id)
|
loadTarget(id)
|
||||||
@ -344,7 +391,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
drawerProfileLongClickListener = { _, profile, _, view ->
|
drawerProfileLongClickListener = { _, profile, _, view ->
|
||||||
if (profile is ProfileDrawerItem) {
|
if (view != null && profile is ProfileDrawerItem) {
|
||||||
showProfileContextMenu(profile, view)
|
showProfileContextMenu(profile, view)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -362,30 +409,32 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
navTarget = navTargetList[0]
|
navTarget = navTargetList[0]
|
||||||
|
|
||||||
var profileListEmpty = drawer.profileListEmpty
|
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
intent?.putExtras(savedInstanceState)
|
intent?.putExtras(savedInstanceState)
|
||||||
savedInstanceState.clear()
|
savedInstanceState.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profileListEmpty) {
|
|
||||||
handleIntent(intent?.extras)
|
|
||||||
}
|
|
||||||
app.db.profileDao().all.observe(this, Observer { profiles ->
|
app.db.profileDao().all.observe(this, Observer { profiles ->
|
||||||
drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList())
|
val allArchived = profiles.all { it.archived }
|
||||||
if (profileListEmpty) {
|
drawer.setProfileList(profiles.filter { it.id >= 0 && (!it.archived || allArchived) }.toMutableList())
|
||||||
profileListEmpty = false
|
//prepend the archived profile if loaded
|
||||||
handleIntent(intent?.extras)
|
if (app.profile.archived && !allArchived) {
|
||||||
}
|
drawer.prependProfile(Profile(
|
||||||
else if (app.profile != null) {
|
id = app.profile.id,
|
||||||
drawer.currentProfile = app.profile.id
|
loginStoreId = app.profile.loginStoreId,
|
||||||
|
loginStoreType = app.profile.loginStoreType,
|
||||||
|
name = app.profile.name,
|
||||||
|
subname = "Archiwum - ${app.profile.subname}"
|
||||||
|
).also {
|
||||||
|
it.archived = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
drawer.currentProfile = App.profileId
|
||||||
})
|
})
|
||||||
|
|
||||||
// if null, getAllFull will load a profile and update drawerItems
|
setDrawerItems()
|
||||||
if (app.profile != null)
|
|
||||||
setDrawerItems()
|
handleIntent(intent?.extras)
|
||||||
|
|
||||||
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
||||||
unreadCounters.map {
|
unreadCounters.map {
|
||||||
@ -395,16 +444,32 @@ class MainActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
b.swipeRefreshLayout.isEnabled = true
|
b.swipeRefreshLayout.isEnabled = true
|
||||||
b.swipeRefreshLayout.setOnRefreshListener { this.syncCurrentFeature() }
|
b.swipeRefreshLayout.setOnRefreshListener { launch { syncCurrentFeature() } }
|
||||||
b.swipeRefreshLayout.setColorSchemeResources(
|
b.swipeRefreshLayout.setColorSchemeResources(
|
||||||
R.color.md_blue_500,
|
R.color.md_blue_500,
|
||||||
R.color.md_amber_500,
|
R.color.md_amber_500,
|
||||||
R.color.md_green_500
|
R.color.md_green_500
|
||||||
)
|
)
|
||||||
|
|
||||||
isStoragePermissionGranted()
|
|
||||||
|
|
||||||
SyncWorker.scheduleNext(app)
|
SyncWorker.scheduleNext(app)
|
||||||
|
UpdateWorker.scheduleNext(app)
|
||||||
|
|
||||||
|
// if loaded profile is archived, switch to the up-to-date version of it
|
||||||
|
if (app.profile.archived) {
|
||||||
|
launch {
|
||||||
|
if (app.profile.archiveId != null) {
|
||||||
|
val profile = withContext(Dispatchers.IO) {
|
||||||
|
app.db.profileDao().getNotArchivedOf(app.profile.archiveId!!)
|
||||||
|
}
|
||||||
|
if (profile != null)
|
||||||
|
loadProfile(profile)
|
||||||
|
else
|
||||||
|
loadProfile(0)
|
||||||
|
} else {
|
||||||
|
loadProfile(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// APP BACKGROUND
|
// APP BACKGROUND
|
||||||
if (app.config.ui.appBackground != null) {
|
if (app.config.ui.appBackground != null) {
|
||||||
@ -438,6 +503,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// WHAT'S NEW DIALOG
|
// WHAT'S NEW DIALOG
|
||||||
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
||||||
|
// force an AppSync after update
|
||||||
|
app.config.sync.lastAppSync = 0L
|
||||||
ChangelogDialog(this)
|
ChangelogDialog(this)
|
||||||
if (app.config.appVersion < 170) {
|
if (app.config.appVersion < 170) {
|
||||||
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
||||||
@ -509,17 +576,25 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var profileListEmptyListener = {
|
|
||||||
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
|
||||||
}
|
|
||||||
private var profileSettingClickListener = { id: Int, view: View? ->
|
private var profileSettingClickListener = { id: Int, view: View? ->
|
||||||
when (id) {
|
when (id) {
|
||||||
DRAWER_PROFILE_ADD_NEW -> {
|
DRAWER_PROFILE_ADD_NEW -> {
|
||||||
profileListEmptyListener()
|
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
||||||
}
|
}
|
||||||
DRAWER_PROFILE_SYNC_ALL -> {
|
DRAWER_PROFILE_SYNC_ALL -> {
|
||||||
EdziennikTask.sync().enqueue(this)
|
EdziennikTask.sync().enqueue(this)
|
||||||
}
|
}
|
||||||
|
DRAWER_PROFILE_MARK_ALL_AS_READ -> { launch {
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
app.db.profileDao().allNow.forEach { profile ->
|
||||||
|
if (profile.loginStoreType != LoginStore.LOGIN_TYPE_LIBRUS)
|
||||||
|
app.db.metadataDao().setAllSeenExceptMessagesAndAnnouncements(profile.id, true)
|
||||||
|
else
|
||||||
|
app.db.metadataDao().setAllSeenExceptMessages(profile.id, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Toast.makeText(this@MainActivity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||||
|
}}
|
||||||
else -> {
|
else -> {
|
||||||
loadTarget(id)
|
loadTarget(id)
|
||||||
}
|
}
|
||||||
@ -535,7 +610,66 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|_____/ \__, |_| |_|\___|
|
|_____/ \__, |_| |_|\___|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
fun syncCurrentFeature() {
|
suspend fun syncCurrentFeature() {
|
||||||
|
if (app.profile.archived) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.profile_archived_title)
|
||||||
|
.setMessage(
|
||||||
|
R.string.profile_archived_text,
|
||||||
|
app.profile.studentSchoolYearStart,
|
||||||
|
app.profile.studentSchoolYearStart + 1
|
||||||
|
)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (app.profile.shouldArchive()) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.profile_archiving_title)
|
||||||
|
.setMessage(
|
||||||
|
R.string.profile_archiving_format,
|
||||||
|
app.profile.dateYearEnd.formattedString
|
||||||
|
)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
if (app.profile.isBeforeYear()) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.profile_year_not_started_title)
|
||||||
|
.setMessage(
|
||||||
|
R.string.profile_year_not_started_format,
|
||||||
|
app.profile.dateSemester1Start.formattedString
|
||||||
|
)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.profile.registerName?.let { registerName ->
|
||||||
|
var status = app.config.sync.registerAvailability[registerName]
|
||||||
|
if (status == null || status.nextCheckAt < currentTimeUnix()) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val api = SzkolnyApi(app)
|
||||||
|
api.runCatching(this@MainActivity) {
|
||||||
|
val availability = getRegisterAvailability()
|
||||||
|
app.config.sync.registerAvailability = availability
|
||||||
|
status = availability[registerName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status?.available != true
|
||||||
|
|| status?.minVersionCode ?: BuildConfig.VERSION_CODE > BuildConfig.VERSION_CODE) {
|
||||||
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
loadTarget(DRAWER_ITEM_HOME)
|
||||||
|
if (status != null)
|
||||||
|
RegisterUnavailableDialog(this, status!!)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
swipeRefreshLayout.isRefreshing = true
|
swipeRefreshLayout.isRefreshing = true
|
||||||
Toast.makeText(this, fragmentToSyncName(navTargetId), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, fragmentToSyncName(navTargetId), Toast.LENGTH_SHORT).show()
|
||||||
val fragmentParam = when (navTargetId) {
|
val fragmentParam = when (navTargetId) {
|
||||||
@ -549,9 +683,23 @@ class MainActivity : AppCompatActivity() {
|
|||||||
EdziennikTask.syncProfile(
|
EdziennikTask.syncProfile(
|
||||||
App.profileId,
|
App.profileId,
|
||||||
listOf(navTargetId to fragmentParam),
|
listOf(navTargetId to fragmentParam),
|
||||||
arguments
|
arguments = arguments
|
||||||
).enqueue(this)
|
).enqueue(this)
|
||||||
}
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
|
fun onUpdateEvent(event: Update) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
UpdateAvailableDialog(this, event)
|
||||||
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
|
fun onRegisterAvailabilityEvent(event: RegisterAvailabilityEvent) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
app.profile.registerName?.let { registerName ->
|
||||||
|
event.data[registerName]?.let {
|
||||||
|
RegisterUnavailableDialog(this, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onApiTaskStartedEvent(event: ApiTaskStartedEvent) {
|
fun onApiTaskStartedEvent(event: ApiTaskStartedEvent) {
|
||||||
swipeRefreshLayout.isRefreshing = true
|
swipeRefreshLayout.isRefreshing = true
|
||||||
@ -564,6 +712,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) {
|
||||||
|
d(TAG, "Profile list is empty. Launch LoginActivity.")
|
||||||
|
app.config.loginFinished = false
|
||||||
|
startActivity(Intent(this, LoginActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
||||||
if (event.profileId == App.profileId) {
|
if (event.profileId == App.profileId) {
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
@ -579,6 +734,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) {
|
fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
if (event.profileId == App.profileId) {
|
if (event.profileId == App.profileId) {
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
subtitleFormat = R.string.toolbar_subtitle
|
subtitleFormat = R.string.toolbar_subtitle
|
||||||
@ -589,11 +745,17 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskAllFinishedEvent(event: ApiTaskAllFinishedEvent) {
|
fun onApiTaskAllFinishedEvent(event: ApiTaskAllFinishedEvent) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskErrorEvent(event: ApiTaskErrorEvent) {
|
fun onApiTaskErrorEvent(event: ApiTaskErrorEvent) {
|
||||||
EventBus.getDefault().removeStickyEvent(event)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
if (event.error.errorCode == ERROR_VULCAN_API_DEPRECATED) {
|
||||||
|
if (event.error.profileId != App.profileId)
|
||||||
|
return
|
||||||
|
ErrorDetailsDialog(this, listOf(event.error))
|
||||||
|
}
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
subtitleFormat = R.string.toolbar_subtitle
|
subtitleFormat = R.string.toolbar_subtitle
|
||||||
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||||
@ -604,7 +766,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
||||||
if (app.appConfig.dontShowAppManagerDialog)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
if (app.config.sync.dontShowAppManagerDialog)
|
||||||
return
|
return
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.app_manager_dialog_title)
|
.setTitle(R.string.app_manager_dialog_title)
|
||||||
@ -626,12 +789,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
||||||
app.appConfig.dontShowAppManagerDialog = true
|
app.config.sync.dontShowAppManagerDialog = true
|
||||||
app.saveConfig("dontShowAppManagerDialog")
|
|
||||||
}
|
}
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onUserActionRequiredEvent(event: UserActionRequiredEvent) {
|
||||||
|
app.userActionManager.execute(this, event.profileId, event.type)
|
||||||
|
}
|
||||||
|
|
||||||
private fun fragmentToSyncName(currentFragment: Int): Int {
|
private fun fragmentToSyncName(currentFragment: Int): Int {
|
||||||
return when (currentFragment) {
|
return when (currentFragment) {
|
||||||
@ -669,26 +835,64 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
d(TAG, "}")
|
d(TAG, "}")
|
||||||
|
|
||||||
|
var intentProfileId = -1
|
||||||
|
var intentTargetId = -1
|
||||||
|
|
||||||
|
if (extras?.containsKey("action") == true) {
|
||||||
|
val handled = when (extras.getString("action")) {
|
||||||
|
"serverMessage" -> {
|
||||||
|
ServerMessageDialog(
|
||||||
|
this,
|
||||||
|
extras.getString("serverMessageTitle") ?: getString(R.string.app_name),
|
||||||
|
extras.getString("serverMessageText") ?: ""
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
"feedbackMessage" -> {
|
||||||
|
intentTargetId = TARGET_FEEDBACK
|
||||||
|
false
|
||||||
|
}
|
||||||
|
"userActionRequired" -> {
|
||||||
|
app.userActionManager.execute(
|
||||||
|
this,
|
||||||
|
extras.getInt("profileId"),
|
||||||
|
extras.getInt("type")
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
"createManualEvent" -> {
|
||||||
|
val date = extras.getString("eventDate")?.let { Date.fromY_m_d(it) } ?: Date.getToday()
|
||||||
|
EventManualDialog(
|
||||||
|
this,
|
||||||
|
App.profileId,
|
||||||
|
defaultDate = date
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (handled && !navLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (extras?.containsKey("reloadProfileId") == true) {
|
if (extras?.containsKey("reloadProfileId") == true) {
|
||||||
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
||||||
extras.remove("reloadProfileId")
|
extras.remove("reloadProfileId")
|
||||||
if (reloadProfileId == -1 || (app.profile != null && app.profile.id == reloadProfileId)) {
|
if (reloadProfileId == -1 || app.profile.id == reloadProfileId) {
|
||||||
reloadTarget()
|
reloadTarget()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var intentProfileId = -1
|
if (extras?.getInt("profileId", -1) != -1) {
|
||||||
var intentTargetId = -1
|
|
||||||
|
|
||||||
if (extras?.containsKey("profileId") == true) {
|
|
||||||
intentProfileId = extras.getInt("profileId", -1)
|
intentProfileId = extras.getInt("profileId", -1)
|
||||||
extras.remove("profileId")
|
extras?.remove("profileId")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extras?.containsKey("fragmentId") == true) {
|
if (extras?.getInt("fragmentId", -1) != -1) {
|
||||||
intentTargetId = extras.getInt("fragmentId", -1)
|
intentTargetId = extras.getInt("fragmentId", -1)
|
||||||
extras.remove("fragmentId")
|
extras?.remove("fragmentId")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (intentTargetId == -1 && navController.currentDestination?.id == R.id.loadingFragment) {
|
/*if (intentTargetId == -1 && navController.currentDestination?.id == R.id.loadingFragment) {
|
||||||
@ -702,9 +906,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
app.profile == null || app.profile.id == -1 -> {
|
app.profile.id == 0 -> {
|
||||||
if (intentProfileId == -1)
|
if (intentProfileId == -1)
|
||||||
intentProfileId = app.appSharedPrefs.getInt("current_profile_id", 1)
|
intentProfileId = app.config.lastProfileId
|
||||||
loadProfile(intentProfileId, intentTargetId, extras)
|
loadProfile(intentProfileId, intentTargetId, extras)
|
||||||
}
|
}
|
||||||
intentProfileId != -1 -> {
|
intentProfileId != -1 -> {
|
||||||
@ -743,7 +947,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
d(TAG, "Activity started")
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
override fun onStop() {
|
||||||
|
d(TAG, "Activity stopped")
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
d(TAG, "Activity resumed")
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction(Intent.ACTION_MAIN)
|
filter.addAction(Intent.ACTION_MAIN)
|
||||||
registerReceiver(intentReceiver, filter)
|
registerReceiver(intentReceiver, filter)
|
||||||
@ -751,10 +964,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
d(TAG, "Activity paused")
|
||||||
unregisterReceiver(intentReceiver)
|
unregisterReceiver(intentReceiver)
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
override fun onDestroy() {
|
||||||
|
d(TAG, "Activity destroyed")
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
@ -768,15 +986,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
||||||
if (resultCode == Activity.RESULT_CANCELED && false) {
|
if (!app.config.loginFinished)
|
||||||
finish()
|
finish()
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if (!app.config.loginFinished)
|
handleIntent(data?.extras)
|
||||||
finish()
|
|
||||||
else {
|
|
||||||
handleIntent(data?.extras)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -796,37 +1009,51 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
||||||
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
||||||
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
fun loadProfile(profile: Profile) = loadProfile(
|
||||||
//d("NavDebug", "loadProfile(id = $id, drawerSelection = $drawerSelection)")
|
profile,
|
||||||
if (app.profile != null && App.profileId == id) {
|
navTargetId,
|
||||||
|
null,
|
||||||
|
if (app.profile.archived) app.profile.id else null
|
||||||
|
)
|
||||||
|
private fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
||||||
|
if (App.profileId == id) {
|
||||||
drawer.currentProfile = app.profile.id
|
drawer.currentProfile = app.profile.id
|
||||||
loadTarget(drawerSelection, arguments)
|
loadTarget(drawerSelection, arguments)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
AsyncTask.execute {
|
val previousArchivedId = if (app.profile.archived) app.profile.id else null
|
||||||
app.profileLoadById(id)
|
app.profileLoad(id) {
|
||||||
MessagesFragment.pageSelection = -1
|
loadProfile(it, drawerSelection, arguments, previousArchivedId)
|
||||||
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
|
||||||
|
|
||||||
this.runOnUiThread {
|
|
||||||
if (app.profile == null) {
|
|
||||||
if (app.config.loginFinished) {
|
|
||||||
// this shouldn't run
|
|
||||||
profileListEmptyListener()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setDrawerItems()
|
|
||||||
// the drawer profile is updated automatically when the drawer item is clicked
|
|
||||||
// update it manually when switching profiles from other source
|
|
||||||
//if (drawer.currentProfile != app.profile.id)
|
|
||||||
drawer.currentProfile = app.profile.id
|
|
||||||
loadTarget(drawerSelection, arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun loadProfile(profile: Profile, drawerSelection: Int, arguments: Bundle?, previousArchivedId: Int?) {
|
||||||
|
App.profile = profile
|
||||||
|
MessagesFragment.pageSelection = -1
|
||||||
|
|
||||||
|
setDrawerItems()
|
||||||
|
|
||||||
|
if (previousArchivedId != null) {
|
||||||
|
// prevents accidentally removing the first item if the archived profile is not shown
|
||||||
|
drawer.removeProfileById(previousArchivedId)
|
||||||
|
}
|
||||||
|
if (profile.archived) {
|
||||||
|
drawer.prependProfile(Profile(
|
||||||
|
id = profile.id,
|
||||||
|
loginStoreId = profile.loginStoreId,
|
||||||
|
loginStoreType = profile.loginStoreType,
|
||||||
|
name = profile.name,
|
||||||
|
subname = "Archiwum - ${profile.subname}"
|
||||||
|
).also {
|
||||||
|
it.archived = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// the drawer profile is updated automatically when the drawer item is clicked
|
||||||
|
// update it manually when switching profiles from other source
|
||||||
|
//if (drawer.currentProfile != app.profile.id)
|
||||||
|
drawer.currentProfile = app.profileId
|
||||||
|
loadTarget(drawerSelection, arguments)
|
||||||
|
}
|
||||||
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
||||||
var loadId = id
|
var loadId = id
|
||||||
if (loadId == -1) {
|
if (loadId == -1) {
|
||||||
@ -842,15 +1069,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
loadTarget(target, arguments)
|
loadTarget(target, arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun loadTarget(target: NavTarget, arguments: Bundle? = null) {
|
private fun loadTarget(target: NavTarget, args: Bundle? = null) {
|
||||||
d("NavDebug", "loadTarget(target = $target, arguments = $arguments)")
|
d("NavDebug", "loadTarget(target = $target, args = $args)")
|
||||||
|
|
||||||
|
val arguments = args ?: navBackStack.firstOrNull { it.first.id == target.id }?.second ?: Bundle()
|
||||||
bottomSheet.close()
|
bottomSheet.close()
|
||||||
bottomSheet.removeAllContextual()
|
bottomSheet.removeAllContextual()
|
||||||
bottomSheet.toggleGroupEnabled = false
|
bottomSheet.toggleGroupEnabled = false
|
||||||
bottomSheet.onCloseListener = null
|
|
||||||
drawer.close()
|
drawer.close()
|
||||||
drawer.setSelection(target.id, fireOnClick = false)
|
if (drawer.getSelection() != target.id)
|
||||||
|
drawer.setSelection(target.id, fireOnClick = false)
|
||||||
navView.toolbar.setTitle(target.title ?: target.name)
|
navView.toolbar.setTitle(target.title ?: target.name)
|
||||||
navView.bottomBar.fabEnable = false
|
navView.bottomBar.fabEnable = false
|
||||||
navView.bottomBar.fabExtended = false
|
navView.bottomBar.fabExtended = false
|
||||||
@ -892,6 +1120,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
navBackStack.removeAt(navBackStack.lastIndex)
|
navBackStack.removeAt(navBackStack.lastIndex)
|
||||||
}
|
}
|
||||||
navTarget = target
|
navTarget = target
|
||||||
|
navArguments = arguments
|
||||||
|
|
||||||
return@let null
|
return@let null
|
||||||
}?.let {
|
}?.let {
|
||||||
@ -901,7 +1130,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
R.anim.task_open_enter,
|
R.anim.task_open_enter,
|
||||||
R.anim.task_open_exit
|
R.anim.task_open_exit
|
||||||
)
|
)
|
||||||
navBackStack.add(navTarget to arguments)
|
navBackStack.add(navTarget to navArguments)
|
||||||
navTarget = target
|
navTarget = target
|
||||||
navArguments = arguments
|
navArguments = arguments
|
||||||
}
|
}
|
||||||
@ -969,7 +1198,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
* that something has changed in the bottom sheet.
|
* that something has changed in the bottom sheet.
|
||||||
*/
|
*/
|
||||||
fun gainAttention() {
|
fun gainAttention() {
|
||||||
if (app.config.ui.bottomSheetOpened || true)
|
if (app.config.ui.bottomSheetOpened)
|
||||||
return
|
return
|
||||||
b.navView.postDelayed({
|
b.navView.postDelayed({
|
||||||
navView.gainAttentionOnBottomBar()
|
navView.gainAttentionOnBottomBar()
|
||||||
@ -998,11 +1227,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val item = DrawerPrimaryItem()
|
val item = DrawerPrimaryItem()
|
||||||
.withIdentifier(target.id.toLong())
|
.withIdentifier(target.id.toLong())
|
||||||
.withName(target.name)
|
.withName(target.name)
|
||||||
.withHiddenInMiniDrawer(!app.config.ui.miniMenuButtons.contains(target.id))
|
.withIsHiddenInMiniDrawer(!app.config.ui.miniMenuButtons.contains(target.id))
|
||||||
.also { if (target.description != null) it.withDescription(target.description!!) }
|
.also { if (target.description != null) it.withDescription(target.description!!) }
|
||||||
.also { if (target.icon != null) it.withIcon(target.icon!!) }
|
.also { if (target.icon != null) it.withIcon(target.icon!!) }
|
||||||
.also { if (target.title != null) it.withAppTitle(getString(target.title!!)) }
|
.also { if (target.title != null) it.withAppTitle(getString(target.title!!)) }
|
||||||
.also { if (target.badgeTypeId != null) it.withBadgeStyle(drawer.badgeStyle)}
|
.also { if (target.badgeTypeId != null) it.withBadgeStyle(drawer.badgeStyle)}
|
||||||
|
.withSelectedBackgroundAnimated(false)
|
||||||
|
|
||||||
if (target.badgeTypeId != null)
|
if (target.badgeTypeId != null)
|
||||||
drawer.addUnreadCounterType(target.badgeTypeId!!, target.id)
|
drawer.addUnreadCounterType(target.badgeTypeId!!, target.id)
|
||||||
@ -1018,12 +1248,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDrawerItems() {
|
fun setDrawerItems() {
|
||||||
d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
|
d("NavDebug", "setDrawerItems() app.profile = ${app.profile}")
|
||||||
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
||||||
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
||||||
|
|
||||||
val supportedFragments = if (app.profile == null) arrayListOf<Int>()
|
val supportedFragments = app.profile.supportedFragments
|
||||||
else app.profile.supportedFragments
|
|
||||||
|
|
||||||
targetPopToHomeList.clear()
|
targetPopToHomeList.clear()
|
||||||
|
|
||||||
@ -1063,7 +1292,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
drawer.addProfileSettings(*drawerProfiles.toTypedArray())
|
drawer.addProfileSettings(*drawerProfiles.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showProfileContextMenu(profile: IProfile<*>, view: View) {
|
private fun showProfileContextMenu(profile: IProfile, view: View) {
|
||||||
val profileId = profile.identifier.toInt()
|
val profileId = profile.identifier.toInt()
|
||||||
val popupMenu = PopupMenu(this, view)
|
val popupMenu = PopupMenu(this, view)
|
||||||
popupMenu.menu.add(0, 1, 1, R.string.profile_menu_open_settings)
|
popupMenu.menu.add(0, 1, 1, R.string.profile_menu_open_settings)
|
||||||
@ -1076,7 +1305,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
loadTarget(DRAWER_ITEM_SETTINGS, null)
|
loadTarget(DRAWER_ITEM_SETTINGS, null)
|
||||||
} else if (item.itemId == 2) {
|
} else if (item.itemId == 2) {
|
||||||
ProfileRemoveDialog(this, profileId, profile.name?.getText(this)?.toString() ?: "?")
|
ProfileRemoveDialog(this, profileId, profile.name?.getText(this) ?: "?")
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -1087,7 +1316,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private var targetHomeId: Int = -1
|
private var targetHomeId: Int = -1
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (!b.navView.onBackPressed()) {
|
if (!b.navView.onBackPressed()) {
|
||||||
if (App.getConfig().ui.openDrawerOnBackPressed) {
|
if (App.config.ui.openDrawerOnBackPressed && ((navTarget.popTo == null && navTarget.popToHome)
|
||||||
|
|| navTarget.id == DRAWER_ITEM_HOME)) {
|
||||||
b.navView.drawer.toggle()
|
b.navView.drawer.toggle()
|
||||||
} else {
|
} else {
|
||||||
navigateUp()
|
navigateUp()
|
||||||
|
@ -1,350 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.receivers.BootReceiver;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time;
|
|
||||||
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_MAX;
|
|
||||||
|
|
||||||
public class Notifier {
|
|
||||||
|
|
||||||
private static final String TAG = "Notifier";
|
|
||||||
public static final int ID_GET_DATA = 1337000;
|
|
||||||
public static final int ID_GET_DATA_ERROR = 1337001;
|
|
||||||
private static String CHANNEL_GET_DATA_NAME;
|
|
||||||
private static String CHANNEL_GET_DATA_DESC;
|
|
||||||
private static final String GROUP_KEY_GET_DATA = "pl.szczodrzynski.edziennik.GET_DATA";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS = "pl.szczodrzynski.edziennik.NOTIFICATIONS";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS_QUIET = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS_QUIET = "pl.szczodrzynski.edziennik.NOTIFICATIONS_QUIET";
|
|
||||||
|
|
||||||
private static final int ID_UPDATES = 1337003;
|
|
||||||
private static String CHANNEL_UPDATES_NAME;
|
|
||||||
private static String CHANNEL_UPDATES_DESC;
|
|
||||||
private static final String GROUP_KEY_UPDATES = "pl.szczodrzynski.edziennik.UPDATES";
|
|
||||||
|
|
||||||
private App app;
|
|
||||||
public NotificationManager notificationManager;
|
|
||||||
private NotificationCompat.Builder getDataNotificationBuilder;
|
|
||||||
public int notificationColor;
|
|
||||||
|
|
||||||
Notifier(App _app) {
|
|
||||||
this.app = _app;
|
|
||||||
|
|
||||||
CHANNEL_GET_DATA_NAME = app.getString(R.string.notification_channel_get_data_name);
|
|
||||||
CHANNEL_GET_DATA_DESC = app.getString(R.string.notification_channel_get_data_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_NAME = app.getString(R.string.notification_channel_notifications_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_DESC = app.getString(R.string.notification_channel_notifications_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_NAME = app.getString(R.string.notification_channel_notifications_quiet_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_DESC = app.getString(R.string.notification_channel_notifications_quiet_desc);
|
|
||||||
CHANNEL_UPDATES_NAME = app.getString(R.string.notification_channel_updates_name);
|
|
||||||
CHANNEL_UPDATES_DESC = app.getString(R.string.notification_channel_updates_desc);
|
|
||||||
|
|
||||||
notificationColor = ContextCompat.getColor(app.getContext(), R.color.colorPrimary);
|
|
||||||
notificationManager = (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
NotificationChannel channelGetData = new NotificationChannel(GROUP_KEY_GET_DATA, CHANNEL_GET_DATA_NAME, NotificationManager.IMPORTANCE_MIN);
|
|
||||||
channelGetData.setDescription(CHANNEL_GET_DATA_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelGetData);
|
|
||||||
|
|
||||||
NotificationChannel channelNotifications = new NotificationChannel(GROUP_KEY_NOTIFICATIONS, CHANNEL_NOTIFICATIONS_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelNotifications.setDescription(CHANNEL_NOTIFICATIONS_DESC);
|
|
||||||
channelNotifications.enableLights(true);
|
|
||||||
channelNotifications.setLightColor(notificationColor);
|
|
||||||
notificationManager.createNotificationChannel(channelNotifications);
|
|
||||||
|
|
||||||
NotificationChannel channelNotificationsQuiet = new NotificationChannel(GROUP_KEY_NOTIFICATIONS_QUIET, CHANNEL_NOTIFICATIONS_QUIET_NAME, NotificationManager.IMPORTANCE_DEFAULT);
|
|
||||||
channelNotificationsQuiet.setDescription(CHANNEL_NOTIFICATIONS_QUIET_DESC);
|
|
||||||
channelNotificationsQuiet.setSound(null, null);
|
|
||||||
channelNotificationsQuiet.enableVibration(false);
|
|
||||||
notificationManager.createNotificationChannel(channelNotificationsQuiet);
|
|
||||||
|
|
||||||
NotificationChannel channelUpdates = new NotificationChannel(GROUP_KEY_UPDATES, CHANNEL_UPDATES_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelUpdates.setDescription(CHANNEL_UPDATES_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelUpdates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldBeQuiet() {
|
|
||||||
long now = Time.getNow().getInMillis();
|
|
||||||
long start = app.config.getSync().getQuietHoursStart();
|
|
||||||
long end = app.config.getSync().getQuietHoursEnd();
|
|
||||||
if (start > end) {
|
|
||||||
end += 1000 * 60 * 60 * 24;
|
|
||||||
//Log.d(TAG, "Night passing");
|
|
||||||
}
|
|
||||||
if (start > now) {
|
|
||||||
now += 1000 * 60 * 60 * 24;
|
|
||||||
//Log.d(TAG, "Now is smaller");
|
|
||||||
}
|
|
||||||
//Log.d(TAG, "Start is "+start+", now is "+now+", end is "+end);
|
|
||||||
return start > 0 && now >= start && now <= end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNotificationDefaults() {
|
|
||||||
return (shouldBeQuiet() ? 0 : Notification.DEFAULT_ALL);
|
|
||||||
}
|
|
||||||
public String getNotificationGroup() {
|
|
||||||
return shouldBeQuiet() ? GROUP_KEY_NOTIFICATIONS_QUIET : GROUP_KEY_NOTIFICATIONS;
|
|
||||||
}
|
|
||||||
public int getNotificationPriority() {
|
|
||||||
return shouldBeQuiet() ? PRIORITY_DEFAULT : PRIORITY_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _____ _ _____ _
|
|
||||||
| __ \ | | / ____| | |
|
|
||||||
| | | | __ _| |_ __ _ | | __ ___| |_
|
|
||||||
| | | |/ _` | __/ _` | | | |_ |/ _ \ __|
|
|
||||||
| |__| | (_| | || (_| | | |__| | __/ |_
|
|
||||||
|_____/ \__,_|\__\__,_| \_____|\___|\_*/
|
|
||||||
public Notification notificationGetDataShow(int maxProgress) {
|
|
||||||
/*Intent notificationIntent = new Intent(app.getContext(), SyncService.class);
|
|
||||||
notificationIntent.setAction(ACTION_CANCEL);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_GET_DATA)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_get_data_text))
|
|
||||||
//.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_cancel), pendingIntent)
|
|
||||||
//.setGroup(GROUP_KEY_GET_DATA)
|
|
||||||
.setOngoing(true)
|
|
||||||
.setProgress(maxProgress, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_summary))
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProgress(int progress, int maxProgress) {
|
|
||||||
getDataNotificationBuilder.setProgress(maxProgress, progress, false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataAction(int stringResId) {
|
|
||||||
getDataNotificationBuilder.setContentTitle(app.getString(R.string.sync_action_format, app.getString(stringResId)));
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProfile(String profileName) {
|
|
||||||
getDataNotificationBuilder.setContentText(profileName);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataError(String profileName, String error, int failedProfileId) {
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), Notifier.GetDataRetryService.class);
|
|
||||||
notificationIntent.putExtra("failedProfileId", failedProfileId);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
getDataNotificationBuilder.mActions.clear();
|
|
||||||
/*try {
|
|
||||||
//Use reflection clean up old actions
|
|
||||||
Field f = getDataNotificationBuilder.getClass().getDeclaredField("mActions");
|
|
||||||
f.setAccessible(true);
|
|
||||||
f.set(getDataNotificationBuilder, new ArrayList<NotificationCompat.Action>());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder.setProgress(0, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_error_summary))
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
|
||||||
.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_once_again), pendingIntent)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_error_title, profileName))
|
|
||||||
.setContentText(error)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(error))
|
|
||||||
.setOngoing(false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationPost(int id, Notification notification) {
|
|
||||||
notificationManager.notify(id, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationCancel(int id) {
|
|
||||||
notificationManager.cancel(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//public void notificationGetDataHide() {
|
|
||||||
// notificationManager.cancel(ID_GET_DATA);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static class GetDataRetryService extends IntentService {
|
|
||||||
private static final String TAG = "Notifier/GetDataRetry";
|
|
||||||
|
|
||||||
public GetDataRetryService() {
|
|
||||||
super(Notifier.GetDataRetryService.class.getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(Intent intent) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _ __ _ _ _
|
|
||||||
| \ | | | | (_)/ _(_) | | (_)
|
|
||||||
| \| | ___ | |_ _| |_ _ ___ __ _| |_ _ ___ _ __
|
|
||||||
| . ` |/ _ \| __| | _| |/ __/ _` | __| |/ _ \| '_ \
|
|
||||||
| |\ | (_) | |_| | | | | (_| (_| | |_| | (_) | | | |
|
|
||||||
|_| \_|\___/ \__|_|_| |_|\___\__,_|\__|_|\___/|_| |*/
|
|
||||||
public void add(pl.szczodrzynski.edziennik.utils.models.Notification notification) {
|
|
||||||
app.appConfig.notifications.add(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postAll() {
|
|
||||||
Collections.sort(app.appConfig.notifications, (o1, o2) -> (o2.addedDate - o1.addedDate > 0) ? 1 : (o2.addedDate - o1.addedDate < 0) ? -1 : 0);
|
|
||||||
|
|
||||||
if (app.appConfig.notifications.size() > 40) {
|
|
||||||
app.appConfig.notifications.subList(40, app.appConfig.notifications.size() - 1).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int unreadCount = 0;
|
|
||||||
List<pl.szczodrzynski.edziennik.utils.models.Notification> notificationList = new ArrayList<>();
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
if (!notification.notified) {
|
|
||||||
notification.seen = false;
|
|
||||||
notification.notified = true;
|
|
||||||
unreadCount++;
|
|
||||||
if (notificationList.size() < 10) {
|
|
||||||
notificationList.add(notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notification.seen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: notificationList) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
notification.fillIntent(intent);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, notification.id, intent, 0);
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
// title, text, type, date
|
|
||||||
.setContentTitle(notification.title)
|
|
||||||
.setContentText(notification.text)
|
|
||||||
.setSubText(pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type))
|
|
||||||
.setWhen(notification.addedDate)
|
|
||||||
.setTicker(app.getString(R.string.notification_ticker_format, pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type)))
|
|
||||||
// icon, color, lights, priority
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
// channel, group, style
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(notification.text))
|
|
||||||
// intent, auto cancel
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(notification.id, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notificationList.size() > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
intent.setAction("android.intent.action.MAIN");
|
|
||||||
intent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, ID_NOTIFICATIONS,
|
|
||||||
intent, 0);
|
|
||||||
|
|
||||||
NotificationCompat.Builder groupBuilder =
|
|
||||||
new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_new_notification_title_format, unreadCount))
|
|
||||||
.setGroupSummary(true)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle());
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
groupBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_NOTIFICATIONS, groupBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _
|
|
||||||
| | | | | | | |
|
|
||||||
| | | |_ __ __| | __ _| |_ ___ ___
|
|
||||||
| | | | '_ \ / _` |/ _` | __/ _ \/ __|
|
|
||||||
| |__| | |_) | (_| | (_| | || __/\__ \
|
|
||||||
\____/| .__/ \__,_|\__,_|\__\___||___/
|
|
||||||
| |
|
|
||||||
|*/
|
|
||||||
public void notificationUpdatesShow(String updateVersion, String updateUrl, String updateFilename, boolean updateDirect) {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), BootReceiver.NotificationActionService.class)
|
|
||||||
.putExtra("update_version", updateVersion)
|
|
||||||
.putExtra("update_url", updateUrl)
|
|
||||||
.putExtra("update_filename", updateFilename)
|
|
||||||
.putExtra("update_direct", updateDirect);
|
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_UPDATES)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_updates_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_updates_text, updateVersion))
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setTicker(app.getString(R.string.notification_updates_summary))
|
|
||||||
.setPriority(PRIORITY_MAX)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_UPDATES, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationUpdatesHide() {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
notificationManager.cancel(ID_UPDATES);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump() {
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
Log.d(TAG, "Profile"+notification.profileId+" Notification from "+ Date.fromMillis(notification.addedDate).getFormattedString()+" "+ Time.fromMillis(notification.addedDate).getStringHMS()+" - "+notification.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,12 +16,13 @@ import pl.szczodrzynski.edziennik.config.utils.ConfigMigration
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
||||||
companion object {
|
companion object {
|
||||||
const val DATA_VERSION = 2
|
const val DATA_VERSION = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
@ -40,6 +41,25 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mDataVersion = mDataVersion ?: values.get("dataVersion", 0); return mDataVersion ?: 0 }
|
get() { mDataVersion = mDataVersion ?: values.get("dataVersion", 0); return mDataVersion ?: 0 }
|
||||||
set(value) { set("dataVersion", value); mDataVersion = value }
|
set(value) { set("dataVersion", value); mDataVersion = value }
|
||||||
|
|
||||||
|
private var mHash: String? = null
|
||||||
|
var hash: String
|
||||||
|
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
||||||
|
set(value) { set("hash", value); mHash = value }
|
||||||
|
|
||||||
|
private var mLastProfileId: Int? = null
|
||||||
|
var lastProfileId: Int
|
||||||
|
get() { mLastProfileId = mLastProfileId ?: values.get("lastProfileId", 0); return mLastProfileId ?: 0 }
|
||||||
|
set(value) { set("lastProfileId", value); mLastProfileId = value }
|
||||||
|
|
||||||
|
private var mUpdatesChannel: String? = null
|
||||||
|
var updatesChannel: String
|
||||||
|
get() { mUpdatesChannel = mUpdatesChannel ?: values.get("updatesChannel", "release"); return mUpdatesChannel ?: "release" }
|
||||||
|
set(value) { set("updatesChannel", value); mUpdatesChannel = value }
|
||||||
|
private var mUpdate: Update? = null
|
||||||
|
var update: Update?
|
||||||
|
get() { mUpdate = mUpdate ?: values.get("update", null as Update?); return mUpdate ?: null as Update? }
|
||||||
|
set(value) { set("update", value); mUpdate = value }
|
||||||
|
|
||||||
private var mAppVersion: Int? = null
|
private var mAppVersion: Int? = null
|
||||||
var appVersion: Int
|
var appVersion: Int
|
||||||
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
||||||
@ -55,6 +75,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mPrivacyPolicyAccepted = mPrivacyPolicyAccepted ?: values.get("privacyPolicyAccepted", false); return mPrivacyPolicyAccepted ?: false }
|
get() { mPrivacyPolicyAccepted = mPrivacyPolicyAccepted ?: values.get("privacyPolicyAccepted", false); return mPrivacyPolicyAccepted ?: false }
|
||||||
set(value) { set("privacyPolicyAccepted", value); mPrivacyPolicyAccepted = value }
|
set(value) { set("privacyPolicyAccepted", value); mPrivacyPolicyAccepted = value }
|
||||||
|
|
||||||
|
private var mDebugMode: Boolean? = null
|
||||||
|
var debugMode: Boolean
|
||||||
|
get() { mDebugMode = mDebugMode ?: values.get("debugMode", false); return mDebugMode ?: false }
|
||||||
|
set(value) { set("debugMode", value); mDebugMode = value }
|
||||||
|
|
||||||
private var mDevModePassword: String? = null
|
private var mDevModePassword: String? = null
|
||||||
var devModePassword: String?
|
var devModePassword: String?
|
||||||
get() { mDevModePassword = mDevModePassword ?: values.get("devModePassword", null as String?); return mDevModePassword }
|
get() { mDevModePassword = mDevModePassword ?: values.get("devModePassword", null as String?); return mDevModePassword }
|
||||||
@ -80,6 +105,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() }
|
get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() }
|
||||||
set(value) { set("widgetConfigs", value); mWidgetConfigs = value }
|
set(value) { set("widgetConfigs", value); mWidgetConfigs = value }
|
||||||
|
|
||||||
|
private var mArchiverEnabled: Boolean? = null
|
||||||
|
var archiverEnabled: Boolean
|
||||||
|
get() { mArchiverEnabled = mArchiverEnabled ?: values.get("archiverEnabled", true); return mArchiverEnabled ?: true }
|
||||||
|
set(value) { set("archiverEnabled", value); mArchiverEnabled = value }
|
||||||
|
|
||||||
private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow()
|
private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow()
|
||||||
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
|
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
|
||||||
init {
|
init {
|
||||||
@ -90,11 +120,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
ConfigMigration(app, this)
|
ConfigMigration(app, this)
|
||||||
}
|
}
|
||||||
fun getFor(profileId: Int): ProfileConfig {
|
fun getFor(profileId: Int): ProfileConfig {
|
||||||
return profileConfigs[profileId] ?: ProfileConfig(db, profileId, rawEntries)
|
return profileConfigs[profileId] ?: ProfileConfig(db, profileId, db.configDao().getAllNow(profileId)).also {
|
||||||
}
|
profileConfigs[profileId] = it
|
||||||
fun forProfile(): ProfileConfig {
|
}
|
||||||
return profileConfigs[App.profileId] ?: ProfileConfig(db, App.profileId, rawEntries)
|
|
||||||
}
|
}
|
||||||
|
fun forProfile() = getFor(App.profileId)
|
||||||
|
|
||||||
fun setProfile(profileId: Int) {
|
fun setProfile(profileId: Int) {
|
||||||
}
|
}
|
||||||
@ -105,4 +135,4 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
db.configDao().add(ConfigEntry(-1, key, value))
|
db.configDao().add(ConfigEntry(-1, key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,11 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||||
|
|
||||||
class ConfigGrades(private val config: Config) {
|
class ConfigGrades(private val config: Config) {
|
||||||
companion object {
|
|
||||||
const val ORDER_BY_DATE_DESC = 0
|
|
||||||
const val ORDER_BY_SUBJECT_ASC = 1
|
|
||||||
const val ORDER_BY_DATE_ASC = 2
|
|
||||||
const val ORDER_BY_SUBJECT_DESC = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
private var mOrderBy: Int? = null
|
private var mOrderBy: Int? = null
|
||||||
var orderBy: Int
|
var orderBy: Int
|
||||||
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: 0 }
|
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: GradesManager.ORDER_BY_DATE_DESC }
|
||||||
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,33 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.config
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.setMap
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class ConfigSync(private val config: Config) {
|
class ConfigSync(private val config: Config) {
|
||||||
|
private val gson = Gson()
|
||||||
|
|
||||||
|
private var mDontShowAppManagerDialog: Boolean? = null
|
||||||
|
var dontShowAppManagerDialog: Boolean
|
||||||
|
get() { mDontShowAppManagerDialog = mDontShowAppManagerDialog ?: config.values.get("dontShowAppManagerDialog", false); return mDontShowAppManagerDialog ?: false }
|
||||||
|
set(value) { config.set("dontShowAppManagerDialog", value); mDontShowAppManagerDialog = value }
|
||||||
|
|
||||||
private var mSyncEnabled: Boolean? = null
|
private var mSyncEnabled: Boolean? = null
|
||||||
var enabled: Boolean
|
var enabled: Boolean
|
||||||
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
||||||
set(value) { config.set("syncEnabled", value); mSyncEnabled = value }
|
set(value) { config.set("syncEnabled", value); mSyncEnabled = value }
|
||||||
|
|
||||||
|
private var mWebPushEnabled: Boolean? = null
|
||||||
|
var webPushEnabled: Boolean
|
||||||
|
get() { mWebPushEnabled = mWebPushEnabled ?: config.values.get("webPushEnabled", true); return mWebPushEnabled ?: true }
|
||||||
|
set(value) { config.set("webPushEnabled", value); mWebPushEnabled = value }
|
||||||
|
|
||||||
private var mSyncOnlyWifi: Boolean? = null
|
private var mSyncOnlyWifi: Boolean? = null
|
||||||
var onlyWifi: Boolean
|
var onlyWifi: Boolean
|
||||||
get() { mSyncOnlyWifi = mSyncOnlyWifi ?: config.values.get("syncOnlyWifi", false); return mSyncOnlyWifi ?: notifyAboutUpdates }
|
get() { mSyncOnlyWifi = mSyncOnlyWifi ?: config.values.get("syncOnlyWifi", false); return mSyncOnlyWifi ?: notifyAboutUpdates }
|
||||||
@ -29,20 +46,30 @@ class ConfigSync(private val config: Config) {
|
|||||||
get() { mNotifyAboutUpdates = mNotifyAboutUpdates ?: config.values.get("notifyAboutUpdates", true); return mNotifyAboutUpdates ?: true }
|
get() { mNotifyAboutUpdates = mNotifyAboutUpdates ?: config.values.get("notifyAboutUpdates", true); return mNotifyAboutUpdates ?: true }
|
||||||
set(value) { config.set("notifyAboutUpdates", value); mNotifyAboutUpdates = value }
|
set(value) { config.set("notifyAboutUpdates", value); mNotifyAboutUpdates = value }
|
||||||
|
|
||||||
|
private var mLastAppSync: Long? = null
|
||||||
|
var lastAppSync: Long
|
||||||
|
get() { mLastAppSync = mLastAppSync ?: config.values.get("lastAppSync", 0L); return mLastAppSync ?: 0L }
|
||||||
|
set(value) { config.set("lastAppSync", value); mLastAppSync = value }
|
||||||
|
|
||||||
/* ____ _ _ _
|
/* ____ _ _ _
|
||||||
/ __ \ (_) | | | |
|
/ __ \ (_) | | | |
|
||||||
| | | |_ _ _ ___| |_ | |__ ___ _ _ _ __ ___
|
| | | |_ _ _ ___| |_ | |__ ___ _ _ _ __ ___
|
||||||
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
|
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
|
||||||
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
|
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
|
||||||
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
|
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
|
||||||
private var mQuietHoursStart: Long? = null
|
private var mQuietHoursEnabled: Boolean? = null
|
||||||
var quietHoursStart: Long
|
var quietHoursEnabled: Boolean
|
||||||
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", 0L); return mQuietHoursStart ?: 0L }
|
get() { mQuietHoursEnabled = mQuietHoursEnabled ?: config.values.get("quietHoursEnabled", false); return mQuietHoursEnabled ?: false }
|
||||||
|
set(value) { config.set("quietHoursEnabled", value); mQuietHoursEnabled = value }
|
||||||
|
|
||||||
|
private var mQuietHoursStart: Time? = null
|
||||||
|
var quietHoursStart: Time?
|
||||||
|
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", null as Time?); return mQuietHoursStart }
|
||||||
set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value }
|
set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value }
|
||||||
|
|
||||||
private var mQuietHoursEnd: Long? = null
|
private var mQuietHoursEnd: Time? = null
|
||||||
var quietHoursEnd: Long
|
var quietHoursEnd: Time?
|
||||||
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", 0L); return mQuietHoursEnd ?: 0L }
|
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", null as Time?); return mQuietHoursEnd }
|
||||||
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
|
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
|
||||||
|
|
||||||
private var mQuietDuringLessons: Boolean? = null
|
private var mQuietDuringLessons: Boolean? = null
|
||||||
@ -72,6 +99,10 @@ class ConfigSync(private val config: Config) {
|
|||||||
var tokenVulcan: String?
|
var tokenVulcan: String?
|
||||||
get() { mTokenVulcan = mTokenVulcan ?: config.values.get("tokenVulcan", null as String?); return mTokenVulcan }
|
get() { mTokenVulcan = mTokenVulcan ?: config.values.get("tokenVulcan", null as String?); return mTokenVulcan }
|
||||||
set(value) { config.set("tokenVulcan", value); mTokenVulcan = value }
|
set(value) { config.set("tokenVulcan", value); mTokenVulcan = value }
|
||||||
|
private var mTokenVulcanHebe: String? = null
|
||||||
|
var tokenVulcanHebe: String?
|
||||||
|
get() { mTokenVulcanHebe = mTokenVulcanHebe ?: config.values.get("tokenVulcanHebe", null as String?); return mTokenVulcanHebe }
|
||||||
|
set(value) { config.set("tokenVulcanHebe", value); mTokenVulcanHebe = value }
|
||||||
|
|
||||||
private var mTokenMobidziennikList: List<Int>? = null
|
private var mTokenMobidziennikList: List<Int>? = null
|
||||||
var tokenMobidziennikList: List<Int>
|
var tokenMobidziennikList: List<Int>
|
||||||
@ -85,4 +116,13 @@ class ConfigSync(private val config: Config) {
|
|||||||
var tokenVulcanList: List<Int>
|
var tokenVulcanList: List<Int>
|
||||||
get() { mTokenVulcanList = mTokenVulcanList ?: config.values.getIntList("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() }
|
get() { mTokenVulcanList = mTokenVulcanList ?: config.values.getIntList("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() }
|
||||||
set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value }
|
set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value }
|
||||||
}
|
private var mTokenVulcanHebeList: List<Int>? = null
|
||||||
|
var tokenVulcanHebeList: List<Int>
|
||||||
|
get() { mTokenVulcanHebeList = mTokenVulcanHebeList ?: config.values.getIntList("tokenVulcanHebeList", listOf()); return mTokenVulcanHebeList ?: listOf() }
|
||||||
|
set(value) { config.set("tokenVulcanHebeList", value); mTokenVulcanHebeList = value }
|
||||||
|
|
||||||
|
private var mRegisterAvailability: Map<String, RegisterAvailabilityStatus>? = null
|
||||||
|
var registerAvailability: Map<String, RegisterAvailabilityStatus>
|
||||||
|
get() { mRegisterAvailability = mRegisterAvailability ?: config.values.get("registerAvailability", null as String?)?.let { it -> gson.fromJson<Map<String, RegisterAvailabilityStatus>>(it, object: TypeToken<Map<String, RegisterAvailabilityStatus>>(){}.type) }; return mRegisterAvailability ?: mapOf() }
|
||||||
|
set(value) { config.setMap("registerAvailability", value); mRegisterAvailability = value }
|
||||||
|
}
|
||||||
|
@ -7,7 +7,6 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel
|
|
||||||
|
|
||||||
class ConfigUI(private val config: Config) {
|
class ConfigUI(private val config: Config) {
|
||||||
private var mTheme: Int? = null
|
private var mTheme: Int? = null
|
||||||
@ -45,16 +44,6 @@ class ConfigUI(private val config: Config) {
|
|||||||
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
||||||
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
||||||
|
|
||||||
private var mAgendaViewType: Int? = null
|
|
||||||
var agendaViewType: Int
|
|
||||||
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 }
|
|
||||||
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
|
||||||
|
|
||||||
private var mHomeCards: List<HomeCardModel>? = null
|
|
||||||
var homeCards: List<HomeCardModel>
|
|
||||||
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
|
||||||
set(value) { config.set("homeCards", value); mHomeCards = value }
|
|
||||||
|
|
||||||
private var mSnowfall: Boolean? = null
|
private var mSnowfall: Boolean? = null
|
||||||
var snowfall: Boolean
|
var snowfall: Boolean
|
||||||
get() { mSnowfall = mSnowfall ?: config.values.get("snowfall", false); return mSnowfall ?: false }
|
get() { mSnowfall = mSnowfall ?: config.values.get("snowfall", false); return mSnowfall ?: false }
|
||||||
|
@ -9,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.ProfileConfigMigration
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
@ -17,7 +18,7 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
|
|
||||||
class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEntry>) : CoroutineScope, AbstractConfig {
|
class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEntry>) : CoroutineScope, AbstractConfig {
|
||||||
companion object {
|
companion object {
|
||||||
const val DATA_VERSION = 1
|
const val DATA_VERSION = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
@ -27,8 +28,10 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
val values: HashMap<String, String?> = hashMapOf()
|
val values: HashMap<String, String?> = hashMapOf()
|
||||||
|
|
||||||
val grades by lazy { ProfileConfigGrades(this) }
|
val grades by lazy { ProfileConfigGrades(this) }
|
||||||
|
val ui by lazy { ProfileConfigUI(this) }
|
||||||
|
val sync by lazy { ProfileConfigSync(this) }
|
||||||
|
val attendance by lazy { ProfileConfigAttendance(this) }
|
||||||
/*
|
/*
|
||||||
val sync by lazy { ConfigSync(this) }
|
|
||||||
val timetable by lazy { ConfigTimetable(this) }
|
val timetable by lazy { ConfigTimetable(this) }
|
||||||
val grades by lazy { ConfigGrades(this) }*/
|
val grades by lazy { ConfigGrades(this) }*/
|
||||||
|
|
||||||
@ -37,10 +40,15 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
get() { mDataVersion = mDataVersion ?: values.get("dataVersion", 0); return mDataVersion ?: 0 }
|
get() { mDataVersion = mDataVersion ?: values.get("dataVersion", 0); return mDataVersion ?: 0 }
|
||||||
set(value) { set("dataVersion", value); mDataVersion = value }
|
set(value) { set("dataVersion", value); mDataVersion = value }
|
||||||
|
|
||||||
|
private var mHash: String? = null
|
||||||
|
var hash: String
|
||||||
|
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
||||||
|
set(value) { set("hash", value); mHash = value }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
rawEntries.toHashMap(profileId, values)
|
rawEntries.toHashMap(profileId, values)
|
||||||
/*if (dataVersion < DATA_VERSION)
|
if (dataVersion < DATA_VERSION)
|
||||||
ProfileConfigMigration(this)*/
|
ProfileConfigMigration(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: String?) {
|
override fun set(key: String, value: String?) {
|
||||||
@ -49,4 +57,4 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
db.configDao().add(ConfigEntry(profileId, key, value))
|
db.configDao().add(ConfigEntry(profileId, key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-29.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
|
||||||
|
class ProfileConfigAttendance(private val config: ProfileConfig) {
|
||||||
|
private var mAttendancePageSelection: Int? = null
|
||||||
|
var attendancePageSelection: Int
|
||||||
|
get() { mAttendancePageSelection = mAttendancePageSelection ?: config.values.get("attendancePageSelection", 1); return mAttendancePageSelection ?: 1 }
|
||||||
|
set(value) { config.set("attendancePageSelection", value); mAttendancePageSelection = value }
|
||||||
|
|
||||||
|
private var mUseSymbols: Boolean? = null
|
||||||
|
var useSymbols: Boolean
|
||||||
|
get() { mUseSymbols = mUseSymbols ?: config.values.get("useSymbols", false); return mUseSymbols ?: false }
|
||||||
|
set(value) { config.set("useSymbols", value); mUseSymbols = value }
|
||||||
|
|
||||||
|
private var mGroupConsecutiveDays: Boolean? = null
|
||||||
|
var groupConsecutiveDays: Boolean
|
||||||
|
get() { mGroupConsecutiveDays = mGroupConsecutiveDays ?: config.values.get("groupConsecutiveDays", true); return mGroupConsecutiveDays ?: true }
|
||||||
|
set(value) { config.set("groupConsecutiveDays", value); mGroupConsecutiveDays = value }
|
||||||
|
|
||||||
|
private var mShowPresenceInMonth: Boolean? = null
|
||||||
|
var showPresenceInMonth: Boolean
|
||||||
|
get() { mShowPresenceInMonth = mShowPresenceInMonth ?: config.values.get("showPresenceInMonth", false); return mShowPresenceInMonth ?: false }
|
||||||
|
set(value) { config.set("showPresenceInMonth", value); mShowPresenceInMonth = value }
|
||||||
|
}
|
@ -5,9 +5,10 @@
|
|||||||
package pl.szczodrzynski.edziennik.config
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.getFloat
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.COLOR_MODE_WEIGHTED
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
|
|
||||||
class ProfileConfigGrades(private val config: ProfileConfig) {
|
class ProfileConfigGrades(private val config: ProfileConfig) {
|
||||||
private var mColorMode: Int? = null
|
private var mColorMode: Int? = null
|
||||||
@ -20,8 +21,37 @@ class ProfileConfigGrades(private val config: ProfileConfig) {
|
|||||||
get() { mYearAverageMode = mYearAverageMode ?: config.values.get("yearAverageMode", YEAR_ALL_GRADES); return mYearAverageMode ?: YEAR_ALL_GRADES }
|
get() { mYearAverageMode = mYearAverageMode ?: config.values.get("yearAverageMode", YEAR_ALL_GRADES); return mYearAverageMode ?: YEAR_ALL_GRADES }
|
||||||
set(value) { config.set("yearAverageMode", value); mYearAverageMode = value }
|
set(value) { config.set("yearAverageMode", value); mYearAverageMode = value }
|
||||||
|
|
||||||
private var mCountZeroToAvg: Boolean? = null
|
private var mHideImproved: Boolean? = null
|
||||||
var countZeroToAvg: Boolean
|
var hideImproved: Boolean
|
||||||
get() { mCountZeroToAvg = mCountZeroToAvg ?: config.values.get("countZeroToAvg", true); return mCountZeroToAvg ?: true }
|
get() { mHideImproved = mHideImproved ?: config.values.get("hideImproved", false); return mHideImproved ?: false }
|
||||||
set(value) { config.set("countZeroToAvg", value); mCountZeroToAvg = value }
|
set(value) { config.set("hideImproved", value); mHideImproved = value }
|
||||||
|
|
||||||
|
private var mAverageWithoutWeight: Boolean? = null
|
||||||
|
var averageWithoutWeight: Boolean
|
||||||
|
get() { mAverageWithoutWeight = mAverageWithoutWeight ?: config.values.get("averageWithoutWeight", true); return mAverageWithoutWeight ?: true }
|
||||||
|
set(value) { config.set("averageWithoutWeight", value); mAverageWithoutWeight = value }
|
||||||
|
|
||||||
|
private var mPlusValue: Float? = null
|
||||||
|
var plusValue: Float?
|
||||||
|
get() { mPlusValue = mPlusValue ?: config.values.getFloat("plusValue"); return mPlusValue }
|
||||||
|
set(value) { config.set("plusValue", value); mPlusValue = value }
|
||||||
|
private var mMinusValue: Float? = null
|
||||||
|
var minusValue: Float?
|
||||||
|
get() { mMinusValue = mMinusValue ?: config.values.getFloat("minusValue"); return mMinusValue }
|
||||||
|
set(value) { config.set("minusValue", value); mMinusValue = value }
|
||||||
|
|
||||||
|
private var mDontCountEnabled: Boolean? = null
|
||||||
|
var dontCountEnabled: Boolean
|
||||||
|
get() { mDontCountEnabled = mDontCountEnabled ?: config.values.get("dontCountEnabled", false); return mDontCountEnabled ?: false }
|
||||||
|
set(value) { config.set("dontCountEnabled", value); mDontCountEnabled = value }
|
||||||
|
|
||||||
|
private var mDontCountGrades: List<String>? = null
|
||||||
|
var dontCountGrades: List<String>
|
||||||
|
get() { mDontCountGrades = mDontCountGrades ?: config.values.get("dontCountGrades", listOf()); return mDontCountGrades ?: listOf() }
|
||||||
|
set(value) { config.set("dontCountGrades", value); mDontCountGrades = value }
|
||||||
|
|
||||||
|
private var mHideSticksFromOld: Boolean? = null
|
||||||
|
var hideSticksFromOld: Boolean
|
||||||
|
get() { mHideSticksFromOld = mHideSticksFromOld ?: config.values.get("hideSticksFromOld", false); return mHideSticksFromOld ?: false }
|
||||||
|
set(value) { config.set("hideSticksFromOld", value); mHideSticksFromOld = value }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
|
||||||
|
class ProfileConfigSync(private val config: ProfileConfig) {
|
||||||
|
private var mNotificationFilter: List<Int>? = null
|
||||||
|
var notificationFilter: List<Int>
|
||||||
|
get() { mNotificationFilter = mNotificationFilter ?: config.values.get("notificationFilter", listOf()); return mNotificationFilter ?: listOf() }
|
||||||
|
set(value) { config.set("notificationFilter", value); mNotificationFilter = value }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel
|
||||||
|
|
||||||
|
class ProfileConfigUI(private val config: ProfileConfig) {
|
||||||
|
private var mAgendaViewType: Int? = null
|
||||||
|
var agendaViewType: Int
|
||||||
|
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT }
|
||||||
|
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
||||||
|
|
||||||
|
private var mHomeCards: List<HomeCardModel>? = null
|
||||||
|
var homeCards: List<HomeCardModel>
|
||||||
|
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
||||||
|
set(value) { config.set("homeCards", value); mHomeCards = value }
|
||||||
|
}
|
@ -22,4 +22,7 @@ interface ConfigDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
||||||
fun getAllNow(profileId: Int): List<ConfigEntry>
|
fun getAllNow(profileId: Int): List<ConfigEntry>
|
||||||
|
|
||||||
|
@Query("DELETE FROM config WHERE profileId = :profileId")
|
||||||
|
fun clear(profileId: Int)
|
||||||
}
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
|
||||||
|
init { config.apply {
|
||||||
|
val s = "app.appConfig"
|
||||||
|
if (dataVersion < 1) {
|
||||||
|
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
||||||
|
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
||||||
|
sync.interval = p.getString("$s.registerSyncInterval", null)?.toIntOrNull() ?: 3600
|
||||||
|
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
||||||
|
str.replace("[\\[\\]]*".toRegex(), "")
|
||||||
|
.split(",\\s?".toRegex())
|
||||||
|
.mapNotNull { it.toIntOrNull() }
|
||||||
|
}
|
||||||
|
ui.miniMenuButtons = oldButtons ?: listOf(
|
||||||
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
MainActivity.DRAWER_ITEM_GRADES,
|
||||||
|
MainActivity.DRAWER_ITEM_MESSAGES,
|
||||||
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
|
)
|
||||||
|
dataVersion = 1
|
||||||
|
}
|
||||||
|
if (dataVersion < 2) {
|
||||||
|
devModePassword = p.getString("$s.devModePassword", null).fix()
|
||||||
|
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
|
||||||
|
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
|
||||||
|
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
|
||||||
|
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
|
||||||
|
ui.headerBackground = p.getString("$s.headerBackground", null).fix()
|
||||||
|
ui.appBackground = p.getString("$s.appBackground", null).fix()
|
||||||
|
ui.language = p.getString("$s.language", null).fix()
|
||||||
|
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
||||||
|
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
||||||
|
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
||||||
|
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
||||||
|
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
||||||
|
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
||||||
|
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
||||||
|
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
||||||
|
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
||||||
|
|
||||||
|
val startMillis = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
|
||||||
|
val endMillis = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
|
||||||
|
if (startMillis > 0) {
|
||||||
|
try {
|
||||||
|
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
|
||||||
|
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
|
||||||
|
sync.quietHoursEnabled = true
|
||||||
|
}
|
||||||
|
catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sync.quietHoursEnabled = false
|
||||||
|
sync.quietHoursStart = null
|
||||||
|
sync.quietHoursEnd = null
|
||||||
|
}
|
||||||
|
|
||||||
|
sync.tokenMobidziennikList = listOf()
|
||||||
|
sync.tokenVulcanList = listOf()
|
||||||
|
sync.tokenLibrusList = listOf()
|
||||||
|
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
||||||
|
tokens?.forEach {
|
||||||
|
val token = it.value.first
|
||||||
|
when (it.key) {
|
||||||
|
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
||||||
|
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
||||||
|
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataVersion = 2
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
private fun String?.fix(): String? {
|
||||||
|
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,9 @@ fun AbstractConfig.set(key: String, value: JsonElement?) {
|
|||||||
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
|
fun AbstractConfig.set(key: String, value: Any?) {
|
||||||
|
set(key, value?.let { gson.toJson(it) })
|
||||||
|
}
|
||||||
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
@ -46,6 +49,9 @@ fun AbstractConfig.setIntList(key: String, value: List<Int>?) {
|
|||||||
fun AbstractConfig.setLongList(key: String, value: List<Long>?) {
|
fun AbstractConfig.setLongList(key: String, value: List<Long>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
|
fun <K, V> AbstractConfig.setMap(key: String, value: Map<K, V>?) {
|
||||||
|
set(key, value?.let { gson.toJson(it) })
|
||||||
|
}
|
||||||
|
|
||||||
fun HashMap<String, String?>.get(key: String, default: String?): String? {
|
fun HashMap<String, String?>.get(key: String, default: String?): String? {
|
||||||
return this[key] ?: default
|
return this[key] ?: default
|
||||||
@ -74,6 +80,9 @@ fun HashMap<String, String?>.get(key: String, default: JsonObject?): JsonObject?
|
|||||||
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
||||||
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
||||||
}
|
}
|
||||||
|
inline fun <reified T> HashMap<String, String?>.get(key: String, default: T?): T? {
|
||||||
|
return this[key]?.let { Gson().fromJson(it, T::class.java) } ?: default
|
||||||
|
}
|
||||||
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
||||||
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
||||||
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
||||||
@ -88,10 +97,14 @@ fun HashMap<String, String?>.getLongList(key: String, default: List<Long>?): Lis
|
|||||||
return this[key]?.let { gson.fromJson<List<Long>>(it, object: TypeToken<List<Long>>(){}.type) } ?: default
|
return this[key]?.let { gson.fromJson<List<Long>>(it, object: TypeToken<List<Long>>(){}.type) } ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun HashMap<String, String?>.getFloat(key: String): Float? {
|
||||||
|
return this[key]?.toFloatOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
fun List<ConfigEntry>.toHashMap(profileId: Int, map: HashMap<String, String?>) {
|
fun List<ConfigEntry>.toHashMap(profileId: Int, map: HashMap<String, String?>) {
|
||||||
map.clear()
|
map.clear()
|
||||||
forEach {
|
forEach {
|
||||||
if (it.profileId == profileId)
|
if (it.profileId == profileId)
|
||||||
map[it.key] = it.value
|
map[it.key] = it.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,32 +5,34 @@
|
|||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.reflect.TypeToken
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.BuildConfig
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.HOUR
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN
|
|
||||||
import pl.szczodrzynski.edziennik.config.Config
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class ConfigMigration(app: App, config: Config) {
|
class ConfigMigration(app: App, config: Config) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
||||||
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
if (p.contains("app.appConfig.appTheme")) {
|
||||||
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
// migrate appConfig from app version 3.x and lower.
|
||||||
sync.interval = p.getString("$s.registerSyncEnabled", null)?.toIntOrNull() ?: 3600
|
// Updates dataVersion to level 2.
|
||||||
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
AppConfigMigrationV3(p, config)
|
||||||
str.replace("[\\[\\]]*".toRegex(), "")
|
}
|
||||||
.split(",\\s?".toRegex())
|
|
||||||
.mapNotNull { it.toIntOrNull() }
|
if (dataVersion < 2) {
|
||||||
}
|
appVersion = BuildConfig.VERSION_CODE
|
||||||
ui.miniMenuButtons = oldButtons ?: listOf(
|
loginFinished = false
|
||||||
|
ui.language = null
|
||||||
|
ui.theme = 1
|
||||||
|
ui.appBackground = null
|
||||||
|
ui.headerBackground = null
|
||||||
|
ui.miniMenuVisible = false
|
||||||
|
ui.miniMenuButtons = listOf(
|
||||||
MainActivity.DRAWER_ITEM_HOME,
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
MainActivity.DRAWER_ITEM_TIMETABLE,
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
MainActivity.DRAWER_ITEM_AGENDA,
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
@ -39,46 +41,70 @@ class ConfigMigration(app: App, config: Config) {
|
|||||||
MainActivity.DRAWER_ITEM_HOMEWORK,
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
MainActivity.DRAWER_ITEM_SETTINGS
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
)
|
)
|
||||||
dataVersion = 1
|
sync.enabled = true
|
||||||
}
|
sync.interval = 1*HOUR.toInt()
|
||||||
if (dataVersion < 2) {
|
sync.notifyAboutUpdates = true
|
||||||
devModePassword = p.getString("$s.devModePassword", null).fix()
|
sync.onlyWifi = false
|
||||||
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
|
sync.quietHoursEnabled = false
|
||||||
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
|
sync.quietHoursStart = null
|
||||||
sync.quietHoursStart = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
|
sync.quietHoursEnd = null
|
||||||
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
|
sync.quietDuringLessons = false
|
||||||
sync.quietHoursEnd = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
|
sync.tokenApp = null
|
||||||
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
|
sync.tokenMobidziennik = null
|
||||||
ui.headerBackground = p.getString("$s.headerBackground", null).fix()
|
|
||||||
ui.appBackground = p.getString("$s.appBackground", null).fix()
|
|
||||||
ui.language = p.getString("$s.language", null).fix()
|
|
||||||
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
|
||||||
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
|
||||||
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
|
||||||
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
|
||||||
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
|
||||||
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
|
||||||
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
|
||||||
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
|
||||||
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
|
||||||
|
|
||||||
sync.tokenMobidziennikList = listOf()
|
sync.tokenMobidziennikList = listOf()
|
||||||
sync.tokenVulcanList = listOf()
|
sync.tokenLibrus = null
|
||||||
sync.tokenLibrusList = listOf()
|
sync.tokenLibrusList = listOf()
|
||||||
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
sync.tokenVulcan = null
|
||||||
tokens?.forEach {
|
sync.tokenVulcanList = listOf()
|
||||||
val token = it.value.first
|
timetable.bellSyncMultiplier = 0
|
||||||
when (it.key) {
|
timetable.bellSyncDiff = null
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
timetable.countInSeconds = false
|
||||||
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
grades.orderBy = ORDER_BY_DATE_DESC
|
||||||
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dataVersion = 2
|
dataVersion = 2
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
|
|
||||||
private fun String?.fix(): String? {
|
if (dataVersion < 3) {
|
||||||
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
update = null
|
||||||
}
|
privacyPolicyAccepted = false
|
||||||
|
debugMode = false
|
||||||
|
devModePassword = null
|
||||||
|
appInstalledTime = 0L
|
||||||
|
appRateSnackbarTime = 0L
|
||||||
|
|
||||||
|
dataVersion = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataVersion < 10) {
|
||||||
|
ui.openDrawerOnBackPressed = false
|
||||||
|
ui.snowfall = false
|
||||||
|
ui.bottomSheetOpened = false
|
||||||
|
sync.dontShowAppManagerDialog = false
|
||||||
|
sync.webPushEnabled = true
|
||||||
|
sync.lastAppSync = 0L
|
||||||
|
|
||||||
|
|
||||||
|
dataVersion = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataVersion < 11) {
|
||||||
|
val startMillis = config.values.get("quietHoursStart", 0L)
|
||||||
|
val endMillis = config.values.get("quietHoursEnd", 0L)
|
||||||
|
if (startMillis > 0) {
|
||||||
|
try {
|
||||||
|
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
|
||||||
|
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
|
||||||
|
sync.quietHoursEnabled = true
|
||||||
|
}
|
||||||
|
catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sync.quietHoursEnabled = false
|
||||||
|
sync.quietHoursStart = null
|
||||||
|
sync.quietHoursEnd = null
|
||||||
|
}
|
||||||
|
|
||||||
|
dataVersion = 11
|
||||||
|
}
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,34 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.config.Config
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
|
|
||||||
class ProfileConfigMigration(app: App, config: Config) {
|
class ProfileConfigMigration(config: ProfileConfig) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
if (dataVersion < 1) {
|
||||||
|
grades.colorMode = COLOR_MODE_WEIGHTED
|
||||||
|
grades.yearAverageMode = YEAR_ALL_GRADES
|
||||||
|
grades.hideImproved = false
|
||||||
|
grades.averageWithoutWeight = true
|
||||||
|
grades.plusValue = null
|
||||||
|
grades.minusValue = null
|
||||||
|
grades.dontCountEnabled = false
|
||||||
|
grades.dontCountGrades = listOf()
|
||||||
|
ui.agendaViewType = AGENDA_DEFAULT
|
||||||
|
// no migration for ui.homeCards
|
||||||
|
|
||||||
//dataVersion = 1
|
dataVersion = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataVersion < 2) {
|
if (dataVersion < 2) {
|
||||||
//gradesColorMode do profilu !
|
sync.notificationFilter = sync.notificationFilter + Notification.TYPE_TEACHER_ABSENCE
|
||||||
//agendaViewType do profilu !
|
|
||||||
// app.appConfig.dontCountZeroToAverage do profilu !
|
dataVersion = 2
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,17 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.*
|
import pl.szczodrzynski.edziennik.data.api.task.ErrorReportTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.SzkolnyTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.toApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -26,7 +30,7 @@ import kotlin.math.roundToInt
|
|||||||
class ApiService : Service() {
|
class ApiService : Service() {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "ApiService"
|
const val TAG = "ApiService"
|
||||||
const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.GET_DATA"
|
const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.SYNC"
|
||||||
fun start(context: Context) {
|
fun start(context: Context) {
|
||||||
context.startService(Intent(context, ApiService::class.java))
|
context.startService(Intent(context, ApiService::class.java))
|
||||||
}
|
}
|
||||||
@ -34,35 +38,34 @@ class ApiService : Service() {
|
|||||||
context.startService(Intent(context, ApiService::class.java))
|
context.startService(Intent(context, ApiService::class.java))
|
||||||
EventBus.getDefault().postSticky(request)
|
EventBus.getDefault().postSticky(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastEventTime = System.currentTimeMillis()
|
||||||
|
var taskCancelTries = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private val app by lazy { applicationContext as App }
|
private val app by lazy { applicationContext as App }
|
||||||
|
|
||||||
private val syncingProfiles = mutableListOf<Profile>()
|
private val syncingProfiles = mutableListOf<Profile>()
|
||||||
|
|
||||||
private val finishingTaskQueue = mutableListOf(
|
private var szkolnyTaskFinished = false
|
||||||
SzkolnyTask.sync(syncingProfiles),
|
private val allTaskRequestList = mutableListOf<Any>()
|
||||||
NotifyTask()
|
|
||||||
)
|
|
||||||
private val allTaskList = mutableListOf<IApiTask>()
|
|
||||||
private val taskQueue = mutableListOf<IApiTask>()
|
private val taskQueue = mutableListOf<IApiTask>()
|
||||||
private val errorList = mutableListOf<ApiError>()
|
private val errorList = mutableListOf<ApiError>()
|
||||||
|
|
||||||
private var serviceClosed = false
|
private var serviceClosed = false
|
||||||
|
set(value) { field = value; notification.serviceClosed = value }
|
||||||
private var taskCancelled = false
|
private var taskCancelled = false
|
||||||
private var taskIsRunning = false
|
private var taskIsRunning = false
|
||||||
private var taskRunning: IApiTask? = null // for debug purposes
|
private var taskRunning: IApiTask? = null // for debug purposes
|
||||||
private var taskRunningId = -1
|
private var taskRunningId = -1
|
||||||
|
private var taskStartTime = 0L
|
||||||
private var taskMaximumId = 0
|
private var taskMaximumId = 0
|
||||||
|
|
||||||
private var taskProfileId = -1
|
private var taskProfileId = -1
|
||||||
private var taskProgress = -1f
|
private var taskProgress = -1f
|
||||||
private var taskProgressText: String? = null
|
private var taskProgressText: String? = null
|
||||||
|
|
||||||
private val notification by lazy { EdziennikNotification(this) }
|
private val notification by lazy { EdziennikNotification(app) }
|
||||||
|
|
||||||
private var lastEventTime = System.currentTimeMillis()
|
|
||||||
private var taskCancelTries = 0
|
|
||||||
|
|
||||||
/* ______ _ _ _ _ _____ _ _ _ _
|
/* ______ _ _ _ _ _____ _ _ _ _
|
||||||
| ____| | | (_) (_) | / ____| | | | | | |
|
| ____| | | (_) (_) | / ____| | | | | | |
|
||||||
@ -73,7 +76,7 @@ class ApiService : Service() {
|
|||||||
private val taskCallback = object : EdziennikCallback {
|
private val taskCallback = object : EdziennikCallback {
|
||||||
override fun onCompleted() {
|
override fun onCompleted() {
|
||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished")
|
d(TAG, "Task $taskRunningId (profile $taskProfileId) finished in ${System.currentTimeMillis()-taskStartTime}")
|
||||||
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
|
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
|
||||||
clearTask()
|
clearTask()
|
||||||
|
|
||||||
@ -85,9 +88,16 @@ class ApiService : Service() {
|
|||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
d(TAG, "Task $taskRunningId threw an error - $apiError")
|
d(TAG, "Task $taskRunningId threw an error - $apiError")
|
||||||
apiError.profileId = taskProfileId
|
apiError.profileId = taskProfileId
|
||||||
EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError))
|
|
||||||
errorList.add(apiError)
|
if (app.userActionManager.requiresUserAction(apiError)) {
|
||||||
apiError.throwable?.printStackTrace()
|
app.userActionManager.sendToUser(apiError)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError))
|
||||||
|
errorList.add(apiError)
|
||||||
|
apiError.throwable?.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
if (apiError.isCritical) {
|
if (apiError.isCritical) {
|
||||||
taskRunning?.cancel()
|
taskRunning?.cancel()
|
||||||
notification.setCriticalError().post()
|
notification.setCriticalError().post()
|
||||||
@ -131,15 +141,20 @@ class ApiService : Service() {
|
|||||||
checkIfTaskFrozen()
|
checkIfTaskFrozen()
|
||||||
if (taskIsRunning)
|
if (taskIsRunning)
|
||||||
return
|
return
|
||||||
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) {
|
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && szkolnyTaskFinished)) {
|
||||||
serviceClosed = false
|
|
||||||
allCompleted()
|
allCompleted()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
|
|
||||||
val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0)
|
val task = if (taskQueue.isNotEmpty()) {
|
||||||
|
taskQueue.removeAt(0)
|
||||||
|
} else {
|
||||||
|
szkolnyTaskFinished = true
|
||||||
|
SzkolnyTask(app, syncingProfiles)
|
||||||
|
}
|
||||||
|
|
||||||
task.taskId = ++taskMaximumId
|
task.taskId = ++taskMaximumId
|
||||||
task.prepare(app)
|
task.prepare(app)
|
||||||
taskIsRunning = true
|
taskIsRunning = true
|
||||||
@ -149,7 +164,7 @@ class ApiService : Service() {
|
|||||||
taskProgress = -1f
|
taskProgress = -1f
|
||||||
taskProgressText = task.taskName
|
taskProgressText = task.taskName
|
||||||
|
|
||||||
d(TAG, "Executing task $taskRunningId ($taskProgressText) - $task")
|
d(TAG, "Executing task $taskRunningId - ${task::class.java.name}")
|
||||||
|
|
||||||
// update the notification
|
// update the notification
|
||||||
notification.setCurrentTask(taskRunningId, taskProgressText).post()
|
notification.setCurrentTask(taskRunningId, taskProgressText).post()
|
||||||
@ -159,15 +174,15 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
task.profile?.let { syncingProfiles.add(it) }
|
task.profile?.let { syncingProfiles.add(it) }
|
||||||
|
|
||||||
|
taskStartTime = System.currentTimeMillis()
|
||||||
try {
|
try {
|
||||||
when (task) {
|
when (task) {
|
||||||
is EdziennikTask -> task.run(app, taskCallback)
|
is EdziennikTask -> task.run(app, taskCallback)
|
||||||
is NotifyTask -> task.run(app, taskCallback)
|
|
||||||
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
||||||
is SzkolnyTask -> task.run(app, taskCallback)
|
is SzkolnyTask -> task.run(taskCallback)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
taskCallback.onError(ApiError(TAG, EXCEPTION_API_TASK).withThrowable(e))
|
taskCallback.onError(e.toApiError(TAG))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +229,7 @@ class ApiService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun allCompleted() {
|
private fun allCompleted() {
|
||||||
|
serviceClosed = true
|
||||||
EventBus.getDefault().postSticky(ApiTaskAllFinishedEvent())
|
EventBus.getDefault().postSticky(ApiTaskAllFinishedEvent())
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
@ -229,10 +245,12 @@ class ApiService : Service() {
|
|||||||
EventBus.getDefault().removeStickyEvent(task)
|
EventBus.getDefault().removeStickyEvent(task)
|
||||||
d(TAG, task.toString())
|
d(TAG, task.toString())
|
||||||
|
|
||||||
// fix for duplicated tasks, thank you EventBus
|
if (task is EdziennikTask) {
|
||||||
if (task in allTaskList)
|
// fix for duplicated tasks, thank you EventBus
|
||||||
return
|
if (task.request in allTaskRequestList)
|
||||||
allTaskList += task
|
return
|
||||||
|
allTaskRequestList += task.request
|
||||||
|
}
|
||||||
|
|
||||||
if (task is EdziennikTask) {
|
if (task is EdziennikTask) {
|
||||||
when (task.request) {
|
when (task.request) {
|
||||||
@ -293,11 +311,13 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
d(TAG, "Foreground service onStartCommand")
|
d(TAG, "Foreground service onStartCommand")
|
||||||
startForeground(EdziennikNotification.NOTIFICATION_ID, notification.notification)
|
startForeground(app.notificationChannelsManager.sync.id, notification.notification)
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
d(TAG, "Service destroyed")
|
||||||
|
serviceClosed = true
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ const val FAKE_LIBRUS_TOKEN = "https://librus.szkolny.eu/access_token.php"
|
|||||||
const val FAKE_LIBRUS_ACCOUNT = "/synergia_accounts_fresh.php?login="
|
const val FAKE_LIBRUS_ACCOUNT = "/synergia_accounts_fresh.php?login="
|
||||||
const val FAKE_LIBRUS_ACCOUNTS = "/synergia_accounts.php"
|
const val FAKE_LIBRUS_ACCOUNTS = "/synergia_accounts.php"
|
||||||
|
|
||||||
val LIBRUS_USER_AGENT = "$SYSTEM_USER_AGENT LibrusMobileApp"
|
val LIBRUS_USER_AGENT = "${SYSTEM_USER_AGENT}LibrusMobileApp"
|
||||||
const val SYNERGIA_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/62.0"
|
const val SYNERGIA_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/62.0"
|
||||||
const val LIBRUS_CLIENT_ID = "wmSyUMo8llDAs4y9tJVYY92oyZ6h4lAt7KCuy0Gv"
|
const val LIBRUS_CLIENT_ID = "0RbsDOkV9tyKEQYzlLv5hs3DM1ukrynFI4p6C1Yc"
|
||||||
const val LIBRUS_REDIRECT_URL = "http://localhost/bar"
|
const val LIBRUS_REDIRECT_URL = "app://librus"
|
||||||
const val LIBRUS_AUTHORIZE_URL = "https://portal.librus.pl/oauth2/authorize?client_id=$LIBRUS_CLIENT_ID&redirect_uri=$LIBRUS_REDIRECT_URL&response_type=code"
|
const val LIBRUS_AUTHORIZE_URL = "https://portal.librus.pl/oauth2/authorize?client_id=$LIBRUS_CLIENT_ID&redirect_uri=$LIBRUS_REDIRECT_URL&response_type=code"
|
||||||
const val LIBRUS_LOGIN_URL = "https://portal.librus.pl/rodzina/login/action"
|
const val LIBRUS_LOGIN_URL = "https://portal.librus.pl/rodzina/login/action"
|
||||||
const val LIBRUS_TOKEN_URL = "https://portal.librus.pl/oauth2/access_token"
|
const val LIBRUS_TOKEN_URL = "https://portal.librus.pl/oauth2/access_token"
|
||||||
|
|
||||||
const val LIBRUS_ACCOUNT_URL = "/v2/SynergiaAccounts/fresh/" // + login
|
const val LIBRUS_ACCOUNT_URL = "/v3/SynergiaAccounts/fresh/" // + login
|
||||||
const val LIBRUS_ACCOUNTS_URL = "/v2/SynergiaAccounts"
|
const val LIBRUS_ACCOUNTS_URL = "/v3/SynergiaAccounts"
|
||||||
|
|
||||||
/** https://api.librus.pl/2.0 */
|
/** https://api.librus.pl/2.0 */
|
||||||
const val LIBRUS_API_URL = "https://api.librus.pl/2.0"
|
const val LIBRUS_API_URL = "https://api.librus.pl/2.0"
|
||||||
@ -56,10 +56,14 @@ const val LIBRUS_SYNERGIA_TOKEN_LOGIN_URL = "https://synergia.librus.pl/loguj/to
|
|||||||
const val LIBRUS_MESSAGES_URL = "https://wiadomosci.librus.pl/module"
|
const val LIBRUS_MESSAGES_URL = "https://wiadomosci.librus.pl/module"
|
||||||
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
||||||
|
|
||||||
|
const val LIBRUS_SYNERGIA_HOMEWORK_ATTACHMENT_URL = "https://synergia.librus.pl/homework/downloadFile"
|
||||||
|
const val LIBRUS_SYNERGIA_MESSAGES_ATTACHMENT_URL = "https://synergia.librus.pl/wiadomosci/pobierz_zalacznik"
|
||||||
|
|
||||||
const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
||||||
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
||||||
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
||||||
const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.aspx"
|
const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.aspx"
|
||||||
|
const val IDZIENNIK_WEB_HOME = "mod_panelRodzica/StronaGlowna.aspx"
|
||||||
const val IDZIENNIK_WEB_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec"
|
const val IDZIENNIK_WEB_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec"
|
||||||
const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia"
|
const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia"
|
||||||
const val IDZIENNIK_WEB_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia"
|
const val IDZIENNIK_WEB_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia"
|
||||||
@ -73,6 +77,8 @@ const val IDZIENNIK_WEB_GET_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/Pobier
|
|||||||
const val IDZIENNIK_WEB_GET_RECIPIENT_LIST = "mod_komunikator/WS_wiadomosci.asmx/pobierzListeOdbiorcowPanelRodzic"
|
const val IDZIENNIK_WEB_GET_RECIPIENT_LIST = "mod_komunikator/WS_wiadomosci.asmx/pobierzListeOdbiorcowPanelRodzic"
|
||||||
const val IDZIENNIK_WEB_SEND_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/WyslijWiadomosc"
|
const val IDZIENNIK_WEB_SEND_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/WyslijWiadomosc"
|
||||||
const val IDZIENNIK_WEB_GET_ATTACHMENT = "mod_komunikator/Download.ashx"
|
const val IDZIENNIK_WEB_GET_ATTACHMENT = "mod_komunikator/Download.ashx"
|
||||||
|
const val IDZIENNIK_WEB_GET_HOMEWORK = "mod_panelRodzica/pracaDomowa/WS_pracaDomowa.asmx/pobierzJednaPraceDomowa"
|
||||||
|
const val IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT = "mod_panelRodzica/pracaDomowa.aspx"
|
||||||
|
|
||||||
val IDZIENNIK_API_USER_AGENT = SYSTEM_USER_AGENT
|
val IDZIENNIK_API_USER_AGENT = SYSTEM_USER_AGENT
|
||||||
const val IDZIENNIK_API_URL = "https://iuczniowie.progman.pl/idziennik/api"
|
const val IDZIENNIK_API_URL = "https://iuczniowie.progman.pl/idziennik/api"
|
||||||
@ -86,10 +92,19 @@ val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT
|
|||||||
|
|
||||||
const val VULCAN_API_USER_AGENT = "MobileUserAgent"
|
const val VULCAN_API_USER_AGENT = "MobileUserAgent"
|
||||||
const val VULCAN_API_APP_NAME = "VULCAN-Android-ModulUcznia"
|
const val VULCAN_API_APP_NAME = "VULCAN-Android-ModulUcznia"
|
||||||
const val VULCAN_API_APP_VERSION = "19.4.1.436"
|
const val VULCAN_API_APP_VERSION = "20.5.1.470"
|
||||||
const val VULCAN_API_PASSWORD = "CE75EA598C7743AD9B0B7328DED85B06"
|
const val VULCAN_API_PASSWORD = "CE75EA598C7743AD9B0B7328DED85B06"
|
||||||
const val VULCAN_API_PASSWORD_FAKELOG = "012345678901234567890123456789AB"
|
const val VULCAN_API_PASSWORD_FAKELOG = "012345678901234567890123456789AB"
|
||||||
val VULCAN_API_DEVICE_NAME = "Szkolny.eu ${Build.MODEL}"
|
const val VULCAN_HEBE_USER_AGENT = "Dart/2.10 (dart:io)"
|
||||||
|
const val VULCAN_HEBE_APP_NAME = "DzienniczekPlus 2.0"
|
||||||
|
const val VULCAN_HEBE_APP_VERSION = "21.02.09 (G)"
|
||||||
|
private const val VULCAN_API_DEVICE_NAME_PREFIX = "Szkolny.eu "
|
||||||
|
private const val VULCAN_API_DEVICE_NAME_SUFFIX = " - nie usuwać"
|
||||||
|
val VULCAN_API_DEVICE_NAME by lazy {
|
||||||
|
val base = "$VULCAN_API_DEVICE_NAME_PREFIX${Build.MODEL}"
|
||||||
|
val baseMaxLength = 50 - VULCAN_API_DEVICE_NAME_SUFFIX.length
|
||||||
|
base.take(baseMaxLength) + VULCAN_API_DEVICE_NAME_SUFFIX
|
||||||
|
}
|
||||||
|
|
||||||
const val VULCAN_API_ENDPOINT_CERTIFICATE = "mobile-api/Uczen.v3.UczenStart/Certyfikat"
|
const val VULCAN_API_ENDPOINT_CERTIFICATE = "mobile-api/Uczen.v3.UczenStart/Certyfikat"
|
||||||
const val VULCAN_API_ENDPOINT_STUDENT_LIST = "mobile-api/Uczen.v3.UczenStart/ListaUczniow"
|
const val VULCAN_API_ENDPOINT_STUDENT_LIST = "mobile-api/Uczen.v3.UczenStart/ListaUczniow"
|
||||||
@ -106,5 +121,30 @@ const val VULCAN_API_ENDPOINT_MESSAGES_SENT = "mobile-api/Uczen.v3.Uczen/Wiadomo
|
|||||||
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
|
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_ADD = "mobile-api/Uczen.v3.Uczen/DodajWiadomosc"
|
const val VULCAN_API_ENDPOINT_MESSAGES_ADD = "mobile-api/Uczen.v3.Uczen/DodajWiadomosc"
|
||||||
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
|
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
|
||||||
|
const val VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/WiadomosciZalacznik"
|
||||||
|
const val VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/ZadaniaDomoweZalacznik"
|
||||||
|
const val VULCAN_WEB_ENDPOINT_LUCKY_NUMBER = "Start.mvc/GetKidsLuckyNumbers"
|
||||||
|
const val VULCAN_WEB_ENDPOINT_REGISTER_DEVICE = "RejestracjaUrzadzeniaToken.mvc/Get"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_REGISTER_NEW = "api/mobile/register/new"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_MAIN = "api/mobile/register/hebe"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_PUSH_ALL = "api/mobile/push/all"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_TIMETABLE = "api/mobile/schedule"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_TIMETABLE_CHANGES = "api/mobile/schedule/changes"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_ADDRESSBOOK = "api/mobile/addressbook"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_EXAMS = "api/mobile/exam"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_GRADES = "api/mobile/grade"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY = "api/mobile/grade/summary"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_HOMEWORK = "api/mobile/homework"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_NOTICES = "api/mobile/note"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_ATTENDANCE = "api/mobile/lesson"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_MESSAGES = "api/mobile/message"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS = "api/mobile/message/status"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_MESSAGES_SEND = "api/mobile/message"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER = "api/mobile/school/lucky"
|
||||||
|
|
||||||
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
||||||
|
|
||||||
|
const val PODLASIE_API_VERSION = "1.0.62"
|
||||||
|
const val PODLASIE_API_URL = "https://cpdklaser.zeto.bialystok.pl/api"
|
||||||
|
const val PODLASIE_API_USER_ENDPOINT = "/pobierzDaneUcznia"
|
||||||
|
const val PODLASIE_API_LOGOUT_DEVICES_ENDPOINT = "/wyczyscUrzadzenia"
|
||||||
|
@ -1,209 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_LUCKY_NUMBER
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ANNOUNCEMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_EVENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_GRADE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_NOTICE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_TIMETABLE_LESSON_CHANGE
|
|
||||||
import pl.szczodrzynski.edziennik.getNotificationTitle
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class DataNotifications(val data: Data) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "DataNotifications"
|
|
||||||
}
|
|
||||||
|
|
||||||
val app = data.app
|
|
||||||
val profileId = data.profile?.id ?: -1
|
|
||||||
val profileName = data.profile?.name ?: ""
|
|
||||||
val profile = data.profile
|
|
||||||
val loginStore = data.loginStore
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (profile == null) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
val today = Date.getToday()
|
|
||||||
val todayValue = today.value
|
|
||||||
|
|
||||||
for (lesson in app.db.timetableDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.getString(R.string.notification_lesson_change_format, lesson.getDisplayChangeType(app), if (lesson.displayDate == null) "" else lesson.displayDate!!.formattedString, lesson.changeSubjectName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_TIMETABLE_LESSON_CHANGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_TIMETABLE_LESSON_CHANGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_TIMETABLE,
|
|
||||||
addedDate = lesson.addedDate
|
|
||||||
).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (event in app.db.eventDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = if (event.type == Event.TYPE_HOMEWORK)
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_homework_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_homework_format,
|
|
||||||
event.subjectLongName,
|
|
||||||
event.eventDate.formattedString
|
|
||||||
)
|
|
||||||
else
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_event_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_event_format,
|
|
||||||
event.typeName,
|
|
||||||
event.eventDate.formattedString,
|
|
||||||
event.subjectLongName
|
|
||||||
)
|
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) TYPE_NEW_HOMEWORK else TYPE_NEW_EVENT
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(type),
|
|
||||||
text = text,
|
|
||||||
type = type,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) DRAWER_ITEM_HOMEWORK else DRAWER_ITEM_AGENDA,
|
|
||||||
addedDate = event.addedDate
|
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
|
||||||
}
|
|
||||||
|
|
||||||
for (grade in app.db.gradeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val gradeName = when (grade.type) {
|
|
||||||
TYPE_SEMESTER1_PROPOSED, TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name)
|
|
||||||
TYPE_SEMESTER1_FINAL, TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name)
|
|
||||||
TYPE_YEAR_PROPOSED -> app.getString(R.string.grade_year_proposed_format_2, grade.name)
|
|
||||||
TYPE_YEAR_FINAL -> app.getString(R.string.grade_year_final_format_2, grade.name)
|
|
||||||
else -> grade.name
|
|
||||||
}
|
|
||||||
val text = app.getString(R.string.notification_grade_format, gradeName, grade.subjectLongName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_GRADE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_GRADE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_GRADES,
|
|
||||||
addedDate = grade.addedDate
|
|
||||||
).addExtra("gradeId", grade.id).addExtra("gradesSubjectId", grade.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (notice in app.db.noticeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val noticeTypeStr = if (notice.type == Notice.TYPE_POSITIVE) app.getString(R.string.notification_notice_praise) else if (notice.type == Notice.TYPE_NEGATIVE) app.getString(R.string.notification_notice_warning) else app.getString(R.string.notification_notice_new)
|
|
||||||
val text = app.getString(R.string.notification_notice_format, noticeTypeStr, notice.teacherFullName, Date.fromMillis(notice.addedDate).formattedString)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_NOTICE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_NOTICE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_BEHAVIOUR,
|
|
||||||
addedDate = notice.addedDate
|
|
||||||
).addExtra("noticeId", notice.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (attendance in app.db.attendanceDao().getNotNotifiedNow(profileId)) {
|
|
||||||
var attendanceTypeStr = app.getString(R.string.notification_type_attendance)
|
|
||||||
when (attendance.type) {
|
|
||||||
Attendance.TYPE_ABSENT -> attendanceTypeStr = app.getString(R.string.notification_absence)
|
|
||||||
Attendance.TYPE_ABSENT_EXCUSED -> attendanceTypeStr = app.getString(R.string.notification_absence_excused)
|
|
||||||
Attendance.TYPE_BELATED -> attendanceTypeStr = app.getString(R.string.notification_belated)
|
|
||||||
Attendance.TYPE_BELATED_EXCUSED -> attendanceTypeStr = app.getString(R.string.notification_belated_excused)
|
|
||||||
Attendance.TYPE_RELEASED -> attendanceTypeStr = app.getString(R.string.notification_release)
|
|
||||||
}
|
|
||||||
val text = app.getString(
|
|
||||||
if (attendance.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_attendance_no_lesson_format
|
|
||||||
else
|
|
||||||
R.string.notification_attendance_format,
|
|
||||||
attendanceTypeStr,
|
|
||||||
attendance.subjectLongName,
|
|
||||||
attendance.lessonDate.formattedString
|
|
||||||
)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ATTENDANCE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ATTENDANCE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ATTENDANCE,
|
|
||||||
addedDate = attendance.addedDate
|
|
||||||
).addExtra("attendanceId", attendance.id).addExtra("attendanceSubjectId", attendance.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (announcement in app.db.announcementDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_announcement_format, announcement.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ANNOUNCEMENT),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ANNOUNCEMENT,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ANNOUNCEMENTS,
|
|
||||||
addedDate = announcement.addedDate
|
|
||||||
).addExtra("announcementId", announcement.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (message in app.db.messageDao().getReceivedNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_message_format, message.senderFullName, message.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_MESSAGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_MESSAGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_MESSAGES,
|
|
||||||
addedDate = message.addedDate
|
|
||||||
).addExtra("messageType", Message.TYPE_RECEIVED.toLong()).addExtra("messageId", message.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
val luckyNumbers = app.db.luckyNumberDao().getNotNotifiedNow(profileId)
|
|
||||||
luckyNumbers?.removeAll { it.date < today }
|
|
||||||
luckyNumbers?.forEach { luckyNumber ->
|
|
||||||
val text = when (luckyNumber.date.value) {
|
|
||||||
todayValue -> // LN for today
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_format else R.string.notification_lucky_number_format, luckyNumber.number)
|
|
||||||
todayValue + 1 -> // LN for tomorrow
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_tomorrow_format else R.string.notification_lucky_number_tomorrow_format, luckyNumber.number)
|
|
||||||
else -> // LN for later
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_later_format else R.string.notification_lucky_number_later_format, luckyNumber.date.formattedString, luckyNumber.number)
|
|
||||||
}
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_LUCKY_NUMBER),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_LUCKY_NUMBER,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_HOME,
|
|
||||||
addedDate = luckyNumber.addedDate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.db.metadataDao().setAllNotified(profileId, true)
|
|
||||||
}}
|
|
||||||
}
|
|
@ -8,22 +8,20 @@ import android.app.Notification
|
|||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.Bundle
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
class EdziennikNotification(val context: Context) {
|
class EdziennikNotification(val app: App) {
|
||||||
companion object {
|
private val notificationManager by lazy { app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
||||||
const val NOTIFICATION_ID = 20191001
|
|
||||||
}
|
|
||||||
|
|
||||||
private val notificationManager by lazy { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
|
||||||
|
|
||||||
private val notificationBuilder: NotificationCompat.Builder by lazy {
|
private val notificationBuilder: NotificationCompat.Builder by lazy {
|
||||||
NotificationCompat.Builder(context, ApiService.NOTIFICATION_API_CHANNEL_ID)
|
NotificationCompat.Builder(app, ApiService.NOTIFICATION_API_CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
.setPriority(PRIORITY_MIN)
|
.setPriority(PRIORITY_MIN)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
@ -35,39 +33,42 @@ class EdziennikNotification(val context: Context) {
|
|||||||
|
|
||||||
private var errorCount = 0
|
private var errorCount = 0
|
||||||
private var criticalErrorCount = 0
|
private var criticalErrorCount = 0
|
||||||
|
var serviceClosed = false
|
||||||
|
|
||||||
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = SzkolnyReceiver.getIntent(app, Bundle(
|
||||||
intent.putExtra("task", "TaskCancelRequest")
|
"task" to "TaskCancelRequest",
|
||||||
intent.putExtra("taskId", taskId)
|
"taskId" to taskId
|
||||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
))
|
||||||
|
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) as PendingIntent
|
||||||
}
|
}
|
||||||
private val closePendingIntent: PendingIntent
|
private val closePendingIntent: PendingIntent
|
||||||
get() {
|
get() {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = SzkolnyReceiver.getIntent(app, Bundle(
|
||||||
intent.putExtra("task", "ServiceCloseRequest")
|
"task" to "ServiceCloseRequest"
|
||||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
))
|
||||||
|
return PendingIntent.getBroadcast(app, 0, intent, 0) as PendingIntent
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun errorCountText(): String? {
|
private fun errorCountText(): String? {
|
||||||
var result = ""
|
var result = ""
|
||||||
if (criticalErrorCount > 0) {
|
if (criticalErrorCount > 0) {
|
||||||
result += context.resources.getQuantityString(R.plurals.critical_errors_format, criticalErrorCount, criticalErrorCount)
|
result += app.resources.getQuantityString(R.plurals.critical_errors_format, criticalErrorCount, criticalErrorCount)
|
||||||
}
|
}
|
||||||
if (criticalErrorCount > 0 && errorCount > 0) {
|
if (criticalErrorCount > 0 && errorCount > 0) {
|
||||||
result += ", "
|
result += ", "
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
result += context.resources.getQuantityString(R.plurals.normal_errors_format, errorCount, errorCount)
|
result += app.resources.getQuantityString(R.plurals.normal_errors_format, errorCount, errorCount)
|
||||||
}
|
}
|
||||||
return if (result.isEmpty()) null else result
|
return if (result.isEmpty()) null else result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIdle(): EdziennikNotification {
|
fun setIdle(): EdziennikNotification {
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_title))
|
notificationBuilder.setContentTitle(app.getString(R.string.edziennik_notification_api_title))
|
||||||
notificationBuilder.setProgress(0, 0, false)
|
notificationBuilder.setProgress(0, 0, false)
|
||||||
notificationBuilder.apply {
|
notificationBuilder.apply {
|
||||||
val str = context.getString(R.string.edziennik_notification_api_text)
|
val str = app.getString(R.string.edziennik_notification_api_text)
|
||||||
setStyle(NotificationCompat.BigTextStyle().bigText(str))
|
setStyle(NotificationCompat.BigTextStyle().bigText(str))
|
||||||
setContentText(str)
|
setContentText(str)
|
||||||
}
|
}
|
||||||
@ -81,7 +82,7 @@ class EdziennikNotification(val context: Context) {
|
|||||||
}
|
}
|
||||||
fun setCriticalError(): EdziennikNotification {
|
fun setCriticalError(): EdziennikNotification {
|
||||||
criticalErrorCount++
|
criticalErrorCount++
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_error_title))
|
notificationBuilder.setContentTitle(app.getString(R.string.edziennik_notification_api_error_title))
|
||||||
notificationBuilder.setProgress(0, 0, false)
|
notificationBuilder.setProgress(0, 0, false)
|
||||||
notificationBuilder.apply {
|
notificationBuilder.apply {
|
||||||
val str = errorCountText()
|
val str = errorCountText()
|
||||||
@ -118,7 +119,7 @@ class EdziennikNotification(val context: Context) {
|
|||||||
notificationBuilder.addAction(
|
notificationBuilder.addAction(
|
||||||
NotificationCompat.Action(
|
NotificationCompat.Action(
|
||||||
R.drawable.ic_notification,
|
R.drawable.ic_notification,
|
||||||
context.getString(R.string.edziennik_notification_api_close),
|
app.getString(R.string.edziennik_notification_api_close),
|
||||||
closePendingIntent
|
closePendingIntent
|
||||||
))
|
))
|
||||||
return this
|
return this
|
||||||
@ -128,13 +129,15 @@ class EdziennikNotification(val context: Context) {
|
|||||||
notificationBuilder.addAction(
|
notificationBuilder.addAction(
|
||||||
NotificationCompat.Action(
|
NotificationCompat.Action(
|
||||||
R.drawable.ic_notification,
|
R.drawable.ic_notification,
|
||||||
context.getString(R.string.edziennik_notification_api_cancel),
|
app.getString(R.string.edziennik_notification_api_cancel),
|
||||||
cancelPendingIntent(taskId)
|
cancelPendingIntent(taskId)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun post() {
|
fun post() {
|
||||||
notificationManager.notify(NOTIFICATION_ID, notification)
|
if (serviceClosed)
|
||||||
|
return
|
||||||
|
notificationManager.notify(app.notificationChannelsManager.sync.id, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.EndpointTimer
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_NEVER
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_NEVER
|
||||||
|
|
||||||
fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featureIds: List<Int>, viewId: Int?) {
|
fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?) {
|
||||||
val data = this
|
val data = this
|
||||||
|
|
||||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||||
@ -46,14 +46,19 @@ fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featu
|
|||||||
// add all endpoint IDs and required login methods, filtering using timers
|
// add all endpoint IDs and required login methods, filtering using timers
|
||||||
.onEach { feature ->
|
.onEach { feature ->
|
||||||
feature.endpointIds.forEach { endpoint ->
|
feature.endpointIds.forEach { endpoint ->
|
||||||
|
if (onlyEndpoints?.contains(endpoint.first) == false)
|
||||||
|
return@forEach
|
||||||
(data.endpointTimers
|
(data.endpointTimers
|
||||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id
|
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id
|
||||||
?: -1, endpoint.first))
|
?: -1, endpoint.first))
|
||||||
.let { timer ->
|
.let { timer ->
|
||||||
if (timer.nextSync == SYNC_ALWAYS ||
|
if (
|
||||||
(viewId != null && timer.viewId == viewId) ||
|
onlyEndpoints?.contains(endpoint.first) == true ||
|
||||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
timer.nextSync == SYNC_ALWAYS ||
|
||||||
data.targetEndpointIds.add(endpoint.first)
|
viewId != null && timer.viewId == viewId ||
|
||||||
|
timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp
|
||||||
|
) {
|
||||||
|
data.targetEndpointIds[endpoint.first] = timer.lastSync
|
||||||
requiredLoginMethods.add(endpoint.second)
|
requiredLoginMethods.add(endpoint.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,8 +81,8 @@ fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featu
|
|||||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||||
data.targetLoginMethodIds.sort()
|
data.targetLoginMethodIds.sort()
|
||||||
|
|
||||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
//data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||||
data.targetEndpointIds.sort()
|
//data.targetEndpointIds.sort()
|
||||||
|
|
||||||
progressCount = targetLoginMethodIds.size + targetEndpointIds.size
|
progressCount = targetLoginMethodIds.size + targetEndpointIds.size
|
||||||
progressStep = if (progressCount <= 0) 0f else 100f / progressCount.toFloat()
|
progressStep = if (progressCount <= 0) 0f else 100f / progressCount.toFloat()
|
||||||
@ -91,7 +96,6 @@ fun Data.prepareFor(loginMethods: List<LoginMethod>, loginMethodId: Int) {
|
|||||||
possibleLoginMethods += it.loginMethodId
|
possibleLoginMethods += it.loginMethodId
|
||||||
}
|
}
|
||||||
|
|
||||||
targetEndpointIds.clear()
|
|
||||||
targetLoginMethodIds.clear()
|
targetLoginMethodIds.clear()
|
||||||
|
|
||||||
// check the login method for any dependencies
|
// check the login method for any dependencies
|
||||||
|
@ -32,6 +32,8 @@ const val CODE_LIBRUS_DISCONNECTED = 31
|
|||||||
const val CODE_PROFILE_ARCHIVED = 30*/
|
const val CODE_PROFILE_ARCHIVED = 30*/
|
||||||
|
|
||||||
const val ERROR_APP_CRASH = 1
|
const val ERROR_APP_CRASH = 1
|
||||||
|
const val ERROR_EXCEPTION = 2
|
||||||
|
const val ERROR_API_EXCEPTION = 3
|
||||||
const val ERROR_MESSAGE_NOT_SENT = 10
|
const val ERROR_MESSAGE_NOT_SENT = 10
|
||||||
|
|
||||||
const val ERROR_REQUEST_FAILURE = 50
|
const val ERROR_REQUEST_FAILURE = 50
|
||||||
@ -51,6 +53,7 @@ const val ERROR_REQUEST_FAILURE_SSL_ERROR = 63
|
|||||||
const val ERROR_RESPONSE_EMPTY = 100
|
const val ERROR_RESPONSE_EMPTY = 100
|
||||||
const val ERROR_LOGIN_DATA_MISSING = 101
|
const val ERROR_LOGIN_DATA_MISSING = 101
|
||||||
const val ERROR_PROFILE_MISSING = 105
|
const val ERROR_PROFILE_MISSING = 105
|
||||||
|
const val ERROR_PROFILE_ARCHIVED = 106
|
||||||
const val ERROR_INVALID_LOGIN_MODE = 110
|
const val ERROR_INVALID_LOGIN_MODE = 110
|
||||||
const val ERROR_LOGIN_METHOD_NOT_SATISFIED = 111
|
const val ERROR_LOGIN_METHOD_NOT_SATISFIED = 111
|
||||||
const val ERROR_NOT_IMPLEMENTED = 112
|
const val ERROR_NOT_IMPLEMENTED = 112
|
||||||
@ -58,6 +61,9 @@ const val ERROR_FILE_DOWNLOAD = 113
|
|||||||
|
|
||||||
const val ERROR_NO_STUDENTS_IN_ACCOUNT = 115
|
const val ERROR_NO_STUDENTS_IN_ACCOUNT = 115
|
||||||
|
|
||||||
|
const val ERROR_CAPTCHA_NEEDED = 3000
|
||||||
|
const val ERROR_CAPTCHA_LIBRUS_PORTAL = 3001
|
||||||
|
|
||||||
const val CODE_INTERNAL_LIBRUS_ACCOUNT_410 = 120
|
const val CODE_INTERNAL_LIBRUS_ACCOUNT_410 = 120
|
||||||
const val CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED = 121
|
const val CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED = 121
|
||||||
const val ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED = 124
|
const val ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED = 124
|
||||||
@ -115,6 +121,13 @@ const val ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN = 179
|
|||||||
const val ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN = 180
|
const val ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN = 180
|
||||||
const val ERROR_LIBRUS_API_MAINTENANCE = 181
|
const val ERROR_LIBRUS_API_MAINTENANCE = 181
|
||||||
const val ERROR_LIBRUS_PORTAL_MAINTENANCE = 182
|
const val ERROR_LIBRUS_PORTAL_MAINTENANCE = 182
|
||||||
|
const val ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM = 183
|
||||||
|
const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED = 184
|
||||||
|
const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185
|
||||||
|
const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186
|
||||||
|
const val ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST = 187
|
||||||
|
const val ERROR_LIBRUS_MESSAGES_ATTACHMENT_NOT_FOUND = 188
|
||||||
|
const val ERROR_LOGIN_LIBRUS_MESSAGES_TIMEOUT = 189
|
||||||
|
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
||||||
@ -129,6 +142,9 @@ const val ERROR_MOBIDZIENNIK_WEB_NO_SESSION_VALUE = 216
|
|||||||
const val ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID = 213
|
const val ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID = 213
|
||||||
const val ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE = 214
|
const val ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE = 214
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID = 215
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID = 215
|
||||||
|
const val ERROR_LOGIN_MOBIDZIENNIK_API2_INVALID_LOGIN = 216
|
||||||
|
const val ERROR_LOGIN_MOBIDZIENNIK_API2_OTHER = 217
|
||||||
|
const val ERROR_MOBIDZIENNIK_WEB_SERVER_PROBLEM = 218
|
||||||
|
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
||||||
@ -143,6 +159,19 @@ const val ERROR_LOGIN_VULCAN_NO_PUPILS = 331
|
|||||||
const val ERROR_VULCAN_API_MAINTENANCE = 340
|
const val ERROR_VULCAN_API_MAINTENANCE = 340
|
||||||
const val ERROR_VULCAN_API_BAD_REQUEST = 341
|
const val ERROR_VULCAN_API_BAD_REQUEST = 341
|
||||||
const val ERROR_VULCAN_API_OTHER = 342
|
const val ERROR_VULCAN_API_OTHER = 342
|
||||||
|
const val ERROR_VULCAN_ATTACHMENT_DOWNLOAD = 343
|
||||||
|
const val ERROR_VULCAN_WEB_DATA_MISSING = 344
|
||||||
|
const val ERROR_VULCAN_WEB_429 = 345
|
||||||
|
const val ERROR_VULCAN_WEB_OTHER = 346
|
||||||
|
const val ERROR_VULCAN_WEB_NO_CERTIFICATE = 347
|
||||||
|
const val ERROR_VULCAN_WEB_NO_REGISTER = 348
|
||||||
|
const val ERROR_VULCAN_WEB_CERTIFICATE_EXPIRED = 349
|
||||||
|
const val ERROR_VULCAN_WEB_LOGGED_OUT = 350
|
||||||
|
const val ERROR_VULCAN_WEB_CERTIFICATE_POST_FAILED = 351
|
||||||
|
const val ERROR_VULCAN_WEB_GRADUATE_ACCOUNT = 352
|
||||||
|
const val ERROR_VULCAN_WEB_NO_SCHOOLS = 353
|
||||||
|
const val ERROR_VULCAN_HEBE_OTHER = 354
|
||||||
|
const val ERROR_VULCAN_API_DEPRECATED = 390
|
||||||
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
|
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
|
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
|
||||||
@ -173,6 +202,12 @@ const val ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS = 521
|
|||||||
const val ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED = 522
|
const val ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED = 522
|
||||||
const val ERROR_EDUDZIENNIK_WEB_TEAM_MISSING = 530
|
const val ERROR_EDUDZIENNIK_WEB_TEAM_MISSING = 530
|
||||||
|
|
||||||
|
const val ERROR_LOGIN_PODLASIE_API_INVALID_TOKEN = 601
|
||||||
|
const val ERROR_LOGIN_PODLASIE_API_DEVICE_LIMIT = 602
|
||||||
|
const val ERROR_PODLASIE_API_NO_TOKEN = 630
|
||||||
|
const val ERROR_PODLASIE_API_OTHER = 631
|
||||||
|
const val ERROR_PODLASIE_API_DATA_MISSING = 632
|
||||||
|
|
||||||
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
||||||
|
|
||||||
const val EXCEPTION_API_TASK = 900
|
const val EXCEPTION_API_TASK = 900
|
||||||
@ -192,5 +227,10 @@ const val EXCEPTION_IDZIENNIK_WEB_API_REQUEST = 913
|
|||||||
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
|
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
|
||||||
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
||||||
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
||||||
|
const val ERROR_ONEDRIVE_DOWNLOAD = 930
|
||||||
|
const val EXCEPTION_VULCAN_WEB_LOGIN = 931
|
||||||
|
const val EXCEPTION_VULCAN_WEB_REQUEST = 932
|
||||||
|
const val EXCEPTION_PODLASIE_API_REQUEST = 940
|
||||||
|
const val EXCEPTION_VULCAN_HEBE_REQUEST = 950
|
||||||
|
|
||||||
const val LOGIN_NO_ARGUMENTS = 1201
|
const val LOGIN_NO_ARGUMENTS = 1201
|
||||||
|
@ -13,8 +13,8 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
|
|
||||||
internal const val FEATURE_TIMETABLE = 1
|
internal const val FEATURE_TIMETABLE = 1
|
||||||
internal const val FEATURE_AGENDA = 2
|
internal const val FEATURE_AGENDA = 2
|
||||||
@ -41,6 +41,7 @@ internal const val FEATURE_PUSH_CONFIG = 120
|
|||||||
object Features {
|
object Features {
|
||||||
private fun getAllNecessary(): List<Int> = listOf(
|
private fun getAllNecessary(): List<Int> = listOf(
|
||||||
FEATURE_ALWAYS_NEEDED,
|
FEATURE_ALWAYS_NEEDED,
|
||||||
|
FEATURE_PUSH_CONFIG,
|
||||||
FEATURE_STUDENT_INFO,
|
FEATURE_STUDENT_INFO,
|
||||||
FEATURE_STUDENT_NUMBER,
|
FEATURE_STUDENT_NUMBER,
|
||||||
FEATURE_SCHOOL_INFO,
|
FEATURE_SCHOOL_INFO,
|
||||||
|
@ -11,10 +11,14 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginSynergia
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginSynergia
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginApi2
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginApi
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
||||||
|
|
||||||
// librus
|
// librus
|
||||||
@ -26,7 +30,6 @@ import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
|||||||
const val SYNERGIA_API_ENABLED = false
|
const val SYNERGIA_API_ENABLED = false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const val LOGIN_TYPE_IDZIENNIK = 3
|
const val LOGIN_TYPE_IDZIENNIK = 3
|
||||||
|
|
||||||
const val LOGIN_TYPE_TEMPLATE = 21
|
const val LOGIN_TYPE_TEMPLATE = 21
|
||||||
@ -69,13 +72,13 @@ val librusLoginMethods = listOf(
|
|||||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, LibrusLoginSynergia::class.java)
|
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, LibrusLoginSynergia::class.java)
|
||||||
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
||||||
.withRequiredLoginMethod { profile, _ ->
|
.withRequiredLoginMethod { profile, _ ->
|
||||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED
|
if (profile?.hasStudentData("accountPassword") == false || true) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED
|
||||||
},
|
},
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, LibrusLoginMessages::class.java)
|
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, LibrusLoginMessages::class.java)
|
||||||
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
||||||
.withRequiredLoginMethod { profile, _ ->
|
.withRequiredLoginMethod { profile, _ ->
|
||||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED
|
if (profile?.hasStudentData("accountPassword") == false || true) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,27 +89,29 @@ const val LOGIN_METHOD_MOBIDZIENNIK_API2 = 300
|
|||||||
val mobidziennikLoginMethods = listOf(
|
val mobidziennikLoginMethods = listOf(
|
||||||
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_WEB, MobidziennikLoginWeb::class.java)
|
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_WEB, MobidziennikLoginWeb::class.java)
|
||||||
.withIsPossible { _, _ -> true }
|
.withIsPossible { _, _ -> true }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }/*,
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_API2, MobidziennikLoginApi2::class.java)
|
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_API2, MobidziennikLoginApi2::class.java)
|
||||||
.withIsPossible { _, loginStore -> loginStore.hasLoginData("email") }
|
.withIsPossible { profile, _ -> profile?.getStudentData("email", null) != null }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }*/
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
)
|
)
|
||||||
|
|
||||||
const val LOGIN_TYPE_VULCAN = 4
|
const val LOGIN_TYPE_VULCAN = 4
|
||||||
const val LOGIN_MODE_VULCAN_API = 0
|
const val LOGIN_MODE_VULCAN_API = 0
|
||||||
const val LOGIN_MODE_VULCAN_WEB = 1
|
const val LOGIN_MODE_VULCAN_WEB = 1
|
||||||
|
const val LOGIN_MODE_VULCAN_HEBE = 2
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_MAIN = 100
|
const val LOGIN_METHOD_VULCAN_WEB_MAIN = 100
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_NEW = 200
|
const val LOGIN_METHOD_VULCAN_WEB_NEW = 200
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_OLD = 300
|
const val LOGIN_METHOD_VULCAN_WEB_OLD = 300
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_MESSAGES = 400
|
const val LOGIN_METHOD_VULCAN_WEB_MESSAGES = 400
|
||||||
const val LOGIN_METHOD_VULCAN_API = 500
|
const val LOGIN_METHOD_VULCAN_API = 500
|
||||||
|
const val LOGIN_METHOD_VULCAN_HEBE = 600
|
||||||
val vulcanLoginMethods = listOf(
|
val vulcanLoginMethods = listOf(
|
||||||
/*LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_MAIN, VulcanLoginWebMain::class.java)
|
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_MAIN, VulcanLoginWebMain::class.java)
|
||||||
.withIsPossible { _, _ -> false }
|
.withIsPossible { _, loginStore -> loginStore.hasLoginData("webHost") }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_NEW, VulcanLoginWebNew::class.java)
|
/*LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_NEW, VulcanLoginWebNew::class.java)
|
||||||
.withIsPossible { _, _ -> false }
|
.withIsPossible { _, _ -> false }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },
|
||||||
|
|
||||||
@ -115,10 +120,16 @@ val vulcanLoginMethods = listOf(
|
|||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },*/
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },*/
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_API, VulcanLoginApi::class.java)
|
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_API, VulcanLoginApi::class.java)
|
||||||
.withIsPossible { _, _ -> true }
|
.withIsPossible { _, loginStore ->
|
||||||
.withRequiredLoginMethod { _, loginStore ->
|
loginStore.mode == LOGIN_MODE_VULCAN_API
|
||||||
if (loginStore.mode == LOGIN_MODE_VULCAN_WEB) LOGIN_METHOD_VULCAN_WEB_NEW else LOGIN_METHOD_NOT_NEEDED
|
|
||||||
}
|
}
|
||||||
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
||||||
|
|
||||||
|
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_HEBE, VulcanLoginHebe::class.java)
|
||||||
|
.withIsPossible { _, loginStore ->
|
||||||
|
loginStore.mode != LOGIN_MODE_VULCAN_API
|
||||||
|
}
|
||||||
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
)
|
)
|
||||||
|
|
||||||
val idziennikLoginMethods = listOf(
|
val idziennikLoginMethods = listOf(
|
||||||
@ -132,6 +143,7 @@ val idziennikLoginMethods = listOf(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
||||||
|
const val LOGIN_MODE_EDUDZIENNIK_WEB = 0
|
||||||
const val LOGIN_METHOD_EDUDZIENNIK_WEB = 100
|
const val LOGIN_METHOD_EDUDZIENNIK_WEB = 100
|
||||||
val edudziennikLoginMethods = listOf(
|
val edudziennikLoginMethods = listOf(
|
||||||
LoginMethod(LOGIN_TYPE_EDUDZIENNIK, LOGIN_METHOD_EDUDZIENNIK_WEB, EdudziennikLoginWeb::class.java)
|
LoginMethod(LOGIN_TYPE_EDUDZIENNIK, LOGIN_METHOD_EDUDZIENNIK_WEB, EdudziennikLoginWeb::class.java)
|
||||||
@ -139,6 +151,15 @@ val edudziennikLoginMethods = listOf(
|
|||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const val LOGIN_TYPE_PODLASIE = 6
|
||||||
|
const val LOGIN_MODE_PODLASIE_API = 0
|
||||||
|
const val LOGIN_METHOD_PODLASIE_API = 100
|
||||||
|
val podlasieLoginMethods = listOf(
|
||||||
|
LoginMethod(LOGIN_TYPE_PODLASIE, LOGIN_METHOD_PODLASIE_API, PodlasieLoginApi::class.java)
|
||||||
|
.withIsPossible { _, _ -> true }
|
||||||
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
|
)
|
||||||
|
|
||||||
val templateLoginMethods = listOf(
|
val templateLoginMethods = listOf(
|
||||||
LoginMethod(LOGIN_TYPE_TEMPLATE, LOGIN_METHOD_TEMPLATE_WEB, TemplateLoginWeb::class.java)
|
LoginMethod(LOGIN_TYPE_TEMPLATE, LOGIN_METHOD_TEMPLATE_WEB, TemplateLoginWeb::class.java)
|
||||||
.withIsPossible { _, _ -> true }
|
.withIsPossible { _, _ -> true }
|
||||||
|
@ -5,10 +5,15 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api
|
||||||
|
|
||||||
import kotlin.text.RegexOption.DOT_MATCHES_ALL
|
import kotlin.text.RegexOption.DOT_MATCHES_ALL
|
||||||
|
import kotlin.text.RegexOption.IGNORE_CASE
|
||||||
|
|
||||||
object Regexes {
|
object Regexes {
|
||||||
val STYLE_CSS_COLOR by lazy {
|
val STYLE_CSS_COLOR by lazy {
|
||||||
"""color: \w+?;?"?""".toRegex()
|
"""color: (\w+);?""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
|
val NOT_DIGITS by lazy {
|
||||||
|
"""[^0-9]""".toRegex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,7 +44,7 @@ object Regexes {
|
|||||||
"""\(([0-9A-ząęóżźńśłć]*?)\)$""".toRegex(DOT_MATCHES_ALL)
|
"""\(([0-9A-ząęóżźńśłć]*?)\)$""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
val MOBIDZIENNIK_LUCKY_NUMBER by lazy {
|
val MOBIDZIENNIK_LUCKY_NUMBER by lazy {
|
||||||
"""class="szczesliwy_numerek".*>0*([0-9]+)(?:/0*[0-9]+)*</a>""".toRegex(DOT_MATCHES_ALL)
|
"""class="szczesliwy_numerek".*?>0?([0-9]+)/?0?([0-9]+)?</a>""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
val MOBIDZIENNIK_CLASS_CALENDAR by lazy {
|
val MOBIDZIENNIK_CLASS_CALENDAR by lazy {
|
||||||
"""events: (.+),$""".toRegex(RegexOption.MULTILINE)
|
"""events: (.+),$""".toRegex(RegexOption.MULTILINE)
|
||||||
@ -54,9 +59,61 @@ object Regexes {
|
|||||||
val MOBIDZIENNIK_MESSAGE_ATTACHMENT by lazy {
|
val MOBIDZIENNIK_MESSAGE_ATTACHMENT by lazy {
|
||||||
"""href="https://.+?\.mobidziennik.pl/.+?&(?:amp;)?zalacznik=([0-9]+)"(?:.+?<small.+?\(([0-9.]+)\s(M|K|G|)B\))*""".toRegex(DOT_MATCHES_ALL)
|
"""href="https://.+?\.mobidziennik.pl/.+?&(?:amp;)?zalacznik=([0-9]+)"(?:.+?<small.+?\(([0-9.]+)\s(M|K|G|)B\))*""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
val MOBIDZIENNIK_MESSAGE_SENT_READ_BY by lazy {
|
||||||
|
"""([0-9]+)/([0-9]+)""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
val MOBIDZIENNIK_MESSAGE_RECIPIENTS_JSON by lazy {
|
val MOBIDZIENNIK_MESSAGE_RECIPIENTS_JSON by lazy {
|
||||||
"""odbiorcy: (\[.+?\]),${'$'}""".toRegex(RegexOption.MULTILINE)
|
"""odbiorcy: (\[.+?]),${'$'}""".toRegex(RegexOption.MULTILINE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_ACCOUNT_EMAIL by lazy {
|
||||||
|
"""name="email" value="(.+?@.+?\..+?)"""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_TYPES by lazy {
|
||||||
|
"""Legenda:.+?normal;">(.+?)</span>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_TABLE by lazy {
|
||||||
|
"""<table .+?id="obecnosci_tabela">(.+?)</table>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_LESSON_COUNT by lazy {
|
||||||
|
"""rel="([0-9-]{10})" colspan="([0-9]+)"""".toRegex()
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_ENTRIES by lazy {
|
||||||
|
"""font-size:.+?class=".*?">(.*?)</td>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_COLUMNS by lazy {
|
||||||
|
"""<tr><td class="border-right1".+?/td>(.+?)</tr>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_COLUMN by lazy {
|
||||||
|
"""(<td.+?>)(.*?)</td>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_COLUMN_SPAN by lazy {
|
||||||
|
"""colspan="(\d+)"""".toRegex()
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_RANGE by lazy {
|
||||||
|
"""<span>([0-9:]+) - .+? (.+?)</span></a>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_LESSON by lazy {
|
||||||
|
"""<strong>(.+?)</strong>\s*<small>\s*\((.+?),\s*(.+?)\)""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ROW by lazy {
|
||||||
|
"""class="rowRolling">(.+?</div>\s*</td>)""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ITEM by lazy {
|
||||||
|
"""<p><b>(.+?):</b>\s*(.+?)\s*</p>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_BODY by lazy {
|
||||||
|
"""Treść:</b>(.+?)<p><b>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ID by lazy {
|
||||||
|
"""zadanieFormularz\(([0-9]+),""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_HOMEWORK_ATTACHMENT by lazy {
|
||||||
|
"""zalacznik(_zadania)?=([0-9]+)'.+?word-break">(.+?)</td>""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +131,7 @@ object Regexes {
|
|||||||
"""id="ctl00_CzyRodzic" value="([01])" />""".toRegex()
|
"""id="ctl00_CzyRodzic" value="([01])" />""".toRegex()
|
||||||
}
|
}
|
||||||
val IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR by lazy {
|
val IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR by lazy {
|
||||||
"""name="ctl00\\${'$'}dxComboRokSzkolny".+?selected="selected".*?value="([0-9]+)">([0-9]+)/([0-9]+)<""".toRegex(DOT_MATCHES_ALL)
|
"""name="ctl00\${"$"}dxComboRokSzkolny".+?selected="selected".*?value="([0-9]+)">([0-9]+)/([0-9]+)<""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
val IDZIENNIK_LOGIN_FIRST_STUDENT_SELECT by lazy {
|
val IDZIENNIK_LOGIN_FIRST_STUDENT_SELECT by lazy {
|
||||||
"""<select.*?name="ctl00\${"$"}dxComboUczniowie".*?</select>""".toRegex(DOT_MATCHES_ALL)
|
"""<select.*?name="ctl00\${"$"}dxComboUczniowie".*?</select>""".toRegex(DOT_MATCHES_ALL)
|
||||||
@ -85,17 +142,33 @@ object Regexes {
|
|||||||
val IDZIENNIK_MESSAGES_RECIPIENT_PARENT by lazy {
|
val IDZIENNIK_MESSAGES_RECIPIENT_PARENT by lazy {
|
||||||
"""(.+?)\s\((.+)\)""".toRegex()
|
"""(.+?)\s\((.+)\)""".toRegex()
|
||||||
}
|
}
|
||||||
|
/*<span id="ctl00_spanSzczesliwyLos">Szczęśliwy los na dzisiaj to <b>19</b>. Los na jutro to <b>22</b></span>*/
|
||||||
|
val IDZIENNIK_WEB_LUCKY_NUMBER by lazy {
|
||||||
|
"""dzisiaj to <b>([0-9]+)</b>""".toRegex()
|
||||||
|
}
|
||||||
|
val IDZIENNIK_WEB_SELECTED_REGISTER by lazy {
|
||||||
|
"""selected="selected" value="([0-9]+)" data-id-ucznia""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val VULCAN_SHIFT_ANNOTATION by lazy {
|
val VULCAN_SHIFT_ANNOTATION by lazy {
|
||||||
"""\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex()
|
"""\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex()
|
||||||
}
|
}
|
||||||
|
val VULCAN_WEB_PERMISSIONS by lazy {
|
||||||
|
"""permissions: '([A-z0-9/=+\-_|]+?)'""".toRegex()
|
||||||
|
}
|
||||||
|
val VULCAN_WEB_SYMBOL_VALIDATE by lazy {
|
||||||
|
"""[A-z0-9]+""".toRegex(IGNORE_CASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val LIBRUS_ATTACHMENT_KEY by lazy {
|
val LIBRUS_ATTACHMENT_KEY by lazy {
|
||||||
"""singleUseKey=([0-9A-f_]+)""".toRegex()
|
"""singleUseKey=([0-9A-z_]+)""".toRegex()
|
||||||
|
}
|
||||||
|
val LIBRUS_MESSAGE_ID by lazy {
|
||||||
|
"""/wiadomosci/[0-9]+/[0-9]+/([0-9]+?)/""".toRegex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -123,6 +196,9 @@ object Regexes {
|
|||||||
val EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION by lazy {
|
val EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION by lazy {
|
||||||
"""<div class="desc">.*?<p>(.*?)</p>""".toRegex(DOT_MATCHES_ALL)
|
"""<div class="desc">.*?<p>(.*?)</p>""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
val EDUDZIENNIK_HOMEWORK_DESCRIPTION by lazy {
|
||||||
|
"""<div class="desc">(.*?)</div>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
val EDUDZIENNIK_SUBJECT_ID by lazy {
|
val EDUDZIENNIK_SUBJECT_ID by lazy {
|
||||||
"""/Courses/([\w-_]+?)/""".toRegex()
|
"""/Courses/([\w-_]+?)/""".toRegex()
|
||||||
@ -168,4 +244,20 @@ object Regexes {
|
|||||||
val EDUDZIENNIK_TEACHERS by lazy {
|
val EDUDZIENNIK_TEACHERS by lazy {
|
||||||
"""<div class="teacher">.*?<p>(.+?) (.+?)</p>""".toRegex(DOT_MATCHES_ALL)
|
"""<div class="teacher">.*?<p>(.+?) (.+?)</p>""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val LINKIFY_DATE_YMD by lazy {
|
||||||
|
"""(1\d{3}|20\d{2})[\-./](1[0-2]|0?\d)[\-./]([1-2]\d|3[0-1]|0?\d)""".toRegex()
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_DMY by lazy {
|
||||||
|
"""(?<![\d\-./])([1-2]\d|3[0-1]|0?\d)[\-./](1[0-2]|0?\d)(?:[\-./](1\d{3}|2?0?\d{2}))?(?![\d\-/])""".toRegex()
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_ABSOLUTE by lazy {
|
||||||
|
"""([1-3][0-9]|[1-9])\s(sty|lut|mar|kwi|maj|cze|lip|sie|wrz|paź|lis|gru).*?\s(1[0-9]{3}|20[0-9]{2})?""".toRegex(IGNORE_CASE)
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_RELATIVE by lazy {
|
||||||
|
"""za\s([0-9]+)?\s?(dni|dzień|tydzień|tygodnie)""".toRegex(IGNORE_CASE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,52 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.task
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.App
|
import org.greenrobot.eventbus.EventBus
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.Idziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.Idziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.Template
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.Template
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.RegisterAvailabilityEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdziennikTask"
|
private const val TAG = "EdziennikTask"
|
||||||
|
|
||||||
|
var profile: Profile? = null
|
||||||
|
var loginStore: LoginStore? = null
|
||||||
|
|
||||||
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
||||||
fun sync() = EdziennikTask(-1, SyncRequest())
|
fun sync() = EdziennikTask(-1, SyncRequest())
|
||||||
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, arguments))
|
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, onlyEndpoints: List<Int>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, onlyEndpoints, arguments))
|
||||||
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
||||||
fun messageGet(profileId: Int, message: MessageFull) = EdziennikTask(profileId, MessageGetRequest(message))
|
fun messageGet(profileId: Int, message: MessageFull) = EdziennikTask(profileId, MessageGetRequest(message))
|
||||||
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
||||||
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
||||||
fun announcementGet(profileId: Int, announcement: AnnouncementFull) = EdziennikTask(profileId, AnnouncementGetRequest(announcement))
|
fun announcementGet(profileId: Int, announcement: AnnouncementFull) = EdziennikTask(profileId, AnnouncementGetRequest(announcement))
|
||||||
fun attachmentGet(profileId: Int, message: Message, attachmentId: Long, attachmentName: String) = EdziennikTask(profileId, AttachmentGetRequest(message, attachmentId, attachmentName))
|
fun attachmentGet(profileId: Int, owner: Any, attachmentId: Long, attachmentName: String) = EdziennikTask(profileId, AttachmentGetRequest(owner, attachmentId, attachmentName))
|
||||||
fun recipientListGet(profileId: Int) = EdziennikTask(profileId, RecipientListGetRequest())
|
fun recipientListGet(profileId: Int) = EdziennikTask(profileId, RecipientListGetRequest())
|
||||||
|
fun eventGet(profileId: Int, event: EventFull) = EdziennikTask(profileId, EventGetRequest(event))
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var loginStore: LoginStore
|
private lateinit var loginStore: LoginStore
|
||||||
@ -52,17 +67,65 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
// save the profile ID and name as the current task's
|
// save the profile ID and name as the current task's
|
||||||
taskName = app.getString(R.string.edziennik_notification_api_sync_title_format, profile.name)
|
taskName = app.getString(R.string.edziennik_notification_api_sync_title_format, profile.name)
|
||||||
}
|
}
|
||||||
|
EdziennikTask.profile = this.profile
|
||||||
|
EdziennikTask.loginStore = this.loginStore
|
||||||
}
|
}
|
||||||
|
|
||||||
private var edziennikInterface: EdziennikInterface? = null
|
private var edziennikInterface: EdziennikInterface? = null
|
||||||
|
|
||||||
internal fun run(app: App, taskCallback: EdziennikCallback) {
|
internal fun run(app: App, taskCallback: EdziennikCallback) {
|
||||||
|
profile?.let { profile ->
|
||||||
|
if (profile.archived) {
|
||||||
|
d(TAG, "The profile $profileId is archived")
|
||||||
|
taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else if (profile.shouldArchive()) {
|
||||||
|
d(TAG, "The profile $profileId's year ended on ${profile.dateYearEnd}, archiving")
|
||||||
|
ProfileArchiver(app, profile)
|
||||||
|
}
|
||||||
|
if (profile.isBeforeYear()) {
|
||||||
|
d(TAG, "The profile $profileId's school year has not started yet; aborting sync")
|
||||||
|
cancel()
|
||||||
|
taskCallback.onCompleted()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.registerName?.let { registerName ->
|
||||||
|
var status = app.config.sync.registerAvailability[registerName]
|
||||||
|
if (status == null || status.nextCheckAt < currentTimeUnix()) {
|
||||||
|
val api = SzkolnyApi(app)
|
||||||
|
api.runCatching({
|
||||||
|
val availability = getRegisterAvailability()
|
||||||
|
app.config.sync.registerAvailability = availability
|
||||||
|
status = availability[registerName]
|
||||||
|
}, onError = {
|
||||||
|
taskCallback.onError(it.toApiError(TAG))
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status?.available != true
|
||||||
|
|| status?.minVersionCode ?: BuildConfig.VERSION_CODE > BuildConfig.VERSION_CODE) {
|
||||||
|
if (EventBus.getDefault().hasSubscriberForEvent(RegisterAvailabilityEvent::class.java)) {
|
||||||
|
EventBus.getDefault().postSticky(
|
||||||
|
RegisterAvailabilityEvent(app.config.sync.registerAvailability)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
taskCallback.onCompleted()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
edziennikInterface = when (loginStore.type) {
|
edziennikInterface = when (loginStore.type) {
|
||||||
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
||||||
|
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@ -75,18 +138,21 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) }
|
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) }
|
||||||
?: Features.getAllIds(),
|
?: Features.getAllIds(),
|
||||||
viewId = request.viewIds?.get(0)?.first,
|
viewId = request.viewIds?.get(0)?.first,
|
||||||
|
onlyEndpoints = request.onlyEndpoints,
|
||||||
arguments = request.arguments)
|
arguments = request.arguments)
|
||||||
is MessageGetRequest -> edziennikInterface?.getMessage(request.message)
|
is MessageGetRequest -> edziennikInterface?.getMessage(request.message)
|
||||||
is MessageSendRequest -> edziennikInterface?.sendMessage(request.recipients, request.subject, request.text)
|
is MessageSendRequest -> edziennikInterface?.sendMessage(request.recipients, request.subject, request.text)
|
||||||
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
||||||
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
||||||
is AnnouncementGetRequest -> edziennikInterface?.getAnnouncement(request.announcement)
|
is AnnouncementGetRequest -> edziennikInterface?.getAnnouncement(request.announcement)
|
||||||
is AttachmentGetRequest -> edziennikInterface?.getAttachment(request.message, request.attachmentId, request.attachmentName)
|
is AttachmentGetRequest -> edziennikInterface?.getAttachment(request.owner, request.attachmentId, request.attachmentName)
|
||||||
is RecipientListGetRequest -> edziennikInterface?.getRecipientList()
|
is RecipientListGetRequest -> edziennikInterface?.getRecipientList()
|
||||||
|
is EventGetRequest -> edziennikInterface?.getEvent(request.event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
|
d(TAG, "Task ${toString()} cancelling...")
|
||||||
edziennikInterface?.cancel()
|
edziennikInterface?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,12 +162,13 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
|
|
||||||
data class FirstLoginRequest(val loginStore: LoginStore)
|
data class FirstLoginRequest(val loginStore: LoginStore)
|
||||||
class SyncRequest
|
class SyncRequest
|
||||||
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val arguments: JsonObject? = null)
|
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val onlyEndpoints: List<Int>? = null, val arguments: JsonObject? = null)
|
||||||
data class SyncProfileListRequest(val profileList: List<Int>)
|
data class SyncProfileListRequest(val profileList: List<Int>)
|
||||||
data class MessageGetRequest(val message: MessageFull)
|
data class MessageGetRequest(val message: MessageFull)
|
||||||
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
||||||
class AnnouncementsReadRequest
|
class AnnouncementsReadRequest
|
||||||
data class AnnouncementGetRequest(val announcement: AnnouncementFull)
|
data class AnnouncementGetRequest(val announcement: AnnouncementFull)
|
||||||
data class AttachmentGetRequest(val message: Message, val attachmentId: Long, val attachmentName: String)
|
data class AttachmentGetRequest(val owner: Any, val attachmentId: Long, val attachmentName: String)
|
||||||
class RecipientListGetRequest
|
class RecipientListGetRequest
|
||||||
|
data class EventGetRequest(val event: EventFull)
|
||||||
}
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-8-25.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.Intent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
|
class ProfileArchiver(val app: App, val profile: Profile) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "ProfileArchiver"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (profile.archiveId == null)
|
||||||
|
profile.archiveId = profile.id
|
||||||
|
d(TAG, "Processing ${profile.name}#${profile.id}, archiveId = ${profile.archiveId}")
|
||||||
|
|
||||||
|
profile.archived = true
|
||||||
|
app.db.profileDao().add(profile)
|
||||||
|
//app.db.metadataDao().setAllSeen(profile.id, true)
|
||||||
|
app.db.notificationDao().clear(profile.id)
|
||||||
|
app.db.endpointTimerDao().clear(profile.id)
|
||||||
|
d(TAG, "Archived profile ${profile.id} saved")
|
||||||
|
profile.archived = false
|
||||||
|
|
||||||
|
// guess the nearest school year
|
||||||
|
val today = Date.getToday()
|
||||||
|
profile.studentSchoolYearStart = when {
|
||||||
|
today.month <= profile.dateYearEnd.month -> today.year - 1
|
||||||
|
else -> today.year
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default semester dates
|
||||||
|
profile.dateSemester1Start = Date(profile.studentSchoolYearStart, 9, 1)
|
||||||
|
profile.dateSemester2Start = Date(profile.studentSchoolYearStart + 1, 2, 1)
|
||||||
|
profile.dateYearEnd = Date(profile.studentSchoolYearStart + 1, 6, 30)
|
||||||
|
|
||||||
|
val oldId = profile.id
|
||||||
|
val newId = (app.db.profileDao().lastId ?: profile.id) + 1
|
||||||
|
profile.id = newId
|
||||||
|
profile.subname = "Nowy rok szkolny - ${profile.studentSchoolYearStart}"
|
||||||
|
profile.studentClassName = null
|
||||||
|
|
||||||
|
d(TAG, "New profile ID for ${profile.name}: ${profile.id}")
|
||||||
|
|
||||||
|
when (profile.loginStoreType) {
|
||||||
|
LOGIN_TYPE_LIBRUS -> {
|
||||||
|
profile.removeStudentData("isPremium")
|
||||||
|
profile.removeStudentData("pushDeviceId")
|
||||||
|
profile.removeStudentData("startPointsSemester1")
|
||||||
|
profile.removeStudentData("startPointsSemester2")
|
||||||
|
profile.removeStudentData("enablePointGrades")
|
||||||
|
profile.removeStudentData("enableDescriptiveGrades")
|
||||||
|
}
|
||||||
|
LOGIN_TYPE_MOBIDZIENNIK -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
LOGIN_TYPE_VULCAN -> {
|
||||||
|
// DataVulcan.isApiLoginValid() returns false so it will update the semester
|
||||||
|
profile.removeStudentData("currentSemesterEndDate")
|
||||||
|
profile.removeStudentData("studentSemesterId")
|
||||||
|
profile.removeStudentData("studentSemesterNumber")
|
||||||
|
profile.removeStudentData("semester1Id")
|
||||||
|
profile.removeStudentData("semester2Id")
|
||||||
|
profile.removeStudentData("studentClassId")
|
||||||
|
}
|
||||||
|
LOGIN_TYPE_IDZIENNIK -> {
|
||||||
|
profile.removeStudentData("schoolYearId")
|
||||||
|
}
|
||||||
|
LOGIN_TYPE_EDUDZIENNIK -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
LOGIN_TYPE_PODLASIE -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d(TAG, "Processed student data: ${profile.studentData}")
|
||||||
|
|
||||||
|
app.db.profileDao().add(profile)
|
||||||
|
|
||||||
|
if (app.profileId == oldId) {
|
||||||
|
val intent = Intent(
|
||||||
|
Intent.ACTION_MAIN,
|
||||||
|
"profileId" to newId
|
||||||
|
)
|
||||||
|
app.sendBroadcast(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
||||||
|
@ -9,18 +9,19 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetHomework
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -41,9 +42,7 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -54,9 +53,9 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId)
|
data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +95,17 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {}
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
|
||||||
override fun getRecipientList() {}
|
override fun getRecipientList() {}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
EdudziennikLoginWeb(data) {
|
||||||
|
EdudziennikWebGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
|
override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
|
@ -27,60 +27,62 @@ class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useEndpoint(data.targetEndpointIds.removeAt(0)) {
|
val id = data.targetEndpointIds.firstKey()
|
||||||
|
val lastSync = data.targetEndpointIds.remove(id)
|
||||||
|
useEndpoint(id, lastSync) { endpointId ->
|
||||||
data.progress(data.progressStep)
|
data.progress(data.progressStep)
|
||||||
nextEndpoint(onSuccess)
|
nextEndpoint(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_START -> {
|
ENDPOINT_EDUDZIENNIK_WEB_START -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_data)
|
data.startProgress(R.string.edziennik_progress_endpoint_data)
|
||||||
EdudziennikWebStart(data, onSuccess)
|
EdudziennikWebStart(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
||||||
EdudziennikWebTeachers(data, onSuccess)
|
EdudziennikWebTeachers(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
|
ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
EdudziennikWebGrades(data, onSuccess)
|
EdudziennikWebGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
|
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
||||||
EdudziennikWebTimetable(data, onSuccess)
|
EdudziennikWebTimetable(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
||||||
EdudziennikWebExams(data, onSuccess)
|
EdudziennikWebExams(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
|
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
EdudziennikWebAttendance(data, onSuccess)
|
EdudziennikWebAttendance(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
||||||
EdudziennikWebAnnouncements(data, onSuccess)
|
EdudziennikWebAnnouncements(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
|
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
EdudziennikWebHomework(data, onSuccess)
|
EdudziennikWebHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
||||||
EdudziennikWebEvents(data, onSuccess)
|
EdudziennikWebEvents(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
|
ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
EdudziennikWebNotes(data, onSuccess)
|
EdudziennikWebNotes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
|
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
EdudziennikWebLuckyNumber(data, onSuccess)
|
EdudziennikWebLuckyNumber(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
else -> onSuccess()
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
|
|||||||
import im.wangchao.mhttp.Request
|
import im.wangchao.mhttp.Request
|
||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import okhttp3.Cookie
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
open class EdudziennikWeb(open val data: DataEdudziennik) {
|
open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWeb"
|
private const val TAG = "EdudziennikWeb"
|
||||||
}
|
}
|
||||||
@ -24,11 +24,11 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
val profile
|
val profile
|
||||||
get() = data.profile
|
get() = data.profile
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, xhr: Boolean = false, onSuccess: (text: String) -> Unit) {
|
fun webGet(tag: String, endpoint: String, xhr: Boolean = false, semester: Int? = null, onSuccess: (text: String) -> Unit) {
|
||||||
val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) {
|
val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) {
|
||||||
true -> endpoint
|
true -> endpoint
|
||||||
else -> "$endpoint/"
|
else -> "$endpoint/"
|
||||||
}
|
} + (semester?.let { "?semester=" + if(it == -1) "all" else it } ?: "")
|
||||||
|
|
||||||
d(tag, "Request: Edudziennik/Web - $url")
|
d(tag, "Request: Edudziennik/Web - $url")
|
||||||
|
|
||||||
@ -40,6 +40,18 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (semester == null && url.contains("start")) {
|
||||||
|
profile?.also { profile ->
|
||||||
|
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
||||||
|
val semesterCookie = cookies["semester"]?.toIntOrNull()
|
||||||
|
|
||||||
|
semesterCookie?.let { data.currentSemester = it }
|
||||||
|
|
||||||
|
if (semesterCookie == 2 && profile.dateSemester2Start > Date.getToday())
|
||||||
|
profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
onSuccess(text)
|
onSuccess(text)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -62,18 +74,7 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
data.app.cookieJar.set("dziennikel.appspot.com", "sessionid", data.webSessionId)
|
||||||
Cookie.Builder()
|
|
||||||
.name("sessionid")
|
|
||||||
.value(data.webSessionId!!)
|
|
||||||
.domain("dziennikel.appspot.com")
|
|
||||||
.secure().httpOnly().build(),
|
|
||||||
Cookie.Builder()
|
|
||||||
.name("semester")
|
|
||||||
.value((data.currentSemester).toString())
|
|
||||||
.domain("dziennikel.appspot.com")
|
|
||||||
.secure().httpOnly().build()
|
|
||||||
))
|
|
||||||
|
|
||||||
Request.builder()
|
Request.builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
|
@ -11,13 +11,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebAnnouncements"
|
const val TAG = "EdudziennikWebAnnouncements"
|
||||||
}
|
}
|
||||||
@ -43,30 +45,31 @@ class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
|||||||
val addedDate = Date.fromIsoHm(dateString)
|
val addedDate = Date.fromIsoHm(dateString)
|
||||||
|
|
||||||
val announcementObject = Announcement(
|
val announcementObject = Announcement(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
subject,
|
subject = subject,
|
||||||
null,
|
text = null,
|
||||||
startDate,
|
startDate = startDate,
|
||||||
null,
|
endDate = null,
|
||||||
teacher.id,
|
teacherId = teacher.id,
|
||||||
longId
|
addedDate = addedDate
|
||||||
)
|
).also {
|
||||||
|
it.idString = longId
|
||||||
|
}
|
||||||
|
|
||||||
data.announcementIgnoreList.add(announcementObject)
|
data.announcementList.add(announcementObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_ANNOUNCEMENT,
|
Metadata.TYPE_ANNOUNCEMENT,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) }
|
||||||
}
|
}
|
||||||
|
@ -11,31 +11,40 @@ import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPES
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.singleOrNull
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebAttendance"
|
private const val TAG = "EdudziennikWebAttendance"
|
||||||
}
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
private var requestSemester: Int? = null
|
||||||
webGet(TAG, data.studentEndpoint + "Presence") { text ->
|
|
||||||
|
init {
|
||||||
|
if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
|
||||||
|
getAttendances()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAttendances() { data.profile?.also { profile ->
|
||||||
|
webGet(TAG, data.studentEndpoint + "Presence", semester = requestSemester) { text ->
|
||||||
|
|
||||||
val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
|
val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
|
||||||
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
|
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
|
||||||
val symbol = type?.get(1)?.trim()
|
val symbol = type?.get(1)?.trim() ?: "?"
|
||||||
val name = type?.get(2)?.trim()
|
val name = type?.get(2)?.trim() ?: "nieznany rodzaj"
|
||||||
return@map Triple(
|
return@map Triple(
|
||||||
symbol,
|
symbol,
|
||||||
name,
|
name,
|
||||||
when (name?.toLowerCase(Locale.ROOT)) {
|
when (name.toLowerCase(Locale.ROOT)) {
|
||||||
"obecność" -> Attendance.TYPE_PRESENT
|
"obecność" -> Attendance.TYPE_PRESENT
|
||||||
"nieobecność" -> Attendance.TYPE_ABSENT
|
"nieobecność" -> Attendance.TYPE_ABSENT
|
||||||
"spóźnienie" -> Attendance.TYPE_BELATED
|
"spóźnienie" -> Attendance.TYPE_BELATED
|
||||||
@ -43,7 +52,7 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
|||||||
"dzień wolny" -> Attendance.TYPE_DAY_FREE
|
"dzień wolny" -> Attendance.TYPE_DAY_FREE
|
||||||
"brak zajęć" -> Attendance.TYPE_DAY_FREE
|
"brak zajęć" -> Attendance.TYPE_DAY_FREE
|
||||||
"oddelegowany" -> Attendance.TYPE_RELEASED
|
"oddelegowany" -> Attendance.TYPE_RELEASED
|
||||||
else -> Attendance.TYPE_CUSTOM
|
else -> Attendance.TYPE_UNKNOWN
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
@ -53,42 +62,53 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
|||||||
val lessonNumber = attendanceElement[2].toInt()
|
val lessonNumber = attendanceElement[2].toInt()
|
||||||
val attendanceSymbol = attendanceElement[3]
|
val attendanceSymbol = attendanceElement[3]
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date)
|
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
||||||
val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber }
|
val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber }
|
||||||
|
|
||||||
val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32()
|
val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32()
|
||||||
|
|
||||||
val (_, name, type) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol }
|
val (typeSymbol, typeName, baseType) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol }
|
||||||
?: return@forEach
|
?: return@forEach
|
||||||
|
|
||||||
val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime
|
val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime
|
||||||
?: return@forEach
|
?: return@forEach
|
||||||
|
|
||||||
val attendanceObject = Attendance(
|
val attendanceObject = Attendance(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
lesson?.displayTeacherId ?: -1,
|
baseType = baseType,
|
||||||
lesson?.displaySubjectId ?: -1,
|
typeName = typeName,
|
||||||
data.currentSemester,
|
typeShort = data.app.attendanceManager.getTypeShort(baseType),
|
||||||
name,
|
typeSymbol = typeSymbol,
|
||||||
date,
|
typeColor = null,
|
||||||
lesson?.displayStartTime ?: startTime,
|
date = date,
|
||||||
type
|
startTime = lesson?.displayStartTime ?: startTime,
|
||||||
)
|
semester = profile.currentSemester,
|
||||||
|
teacherId = lesson?.displayTeacherId ?: -1,
|
||||||
|
subjectId = lesson?.displaySubjectId ?: -1
|
||||||
|
).also {
|
||||||
|
it.lessonNumber = lessonNumber
|
||||||
|
}
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
data.metadataList.add(Metadata(
|
if (baseType != Attendance.TYPE_PRESENT) {
|
||||||
profileId,
|
data.metadataList.add(Metadata(
|
||||||
Metadata.TYPE_ATTENDANCE,
|
profileId,
|
||||||
id,
|
Metadata.TYPE_ATTENDANCE,
|
||||||
profile.empty,
|
id,
|
||||||
profile.empty,
|
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN,
|
||||||
System.currentTimeMillis()
|
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN
|
||||||
))
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
||||||
onSuccess()
|
requestSemester = null
|
||||||
|
getAttendances()
|
||||||
|
} else {
|
||||||
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
||||||
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) }
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EVENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EVENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebEvents(override val data: DataEdudziennik,
|
class EdudziennikWebEvents(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebEvents"
|
const val TAG = "EdudziennikWebEvents"
|
||||||
}
|
}
|
||||||
@ -37,17 +39,16 @@ class EdudziennikWebEvents(override val data: DataEdudziennik,
|
|||||||
?: return@forEach
|
?: return@forEach
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
null,
|
time = null,
|
||||||
title,
|
topic = title,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_CLASS_EVENT,
|
type = Event.TYPE_CLASS_EVENT,
|
||||||
false,
|
teacherId = -1,
|
||||||
-1,
|
subjectId = -1,
|
||||||
-1,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
@ -56,15 +57,14 @@ class EdudziennikWebEvents(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_EVENT,
|
Metadata.TYPE_EVENT,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) }
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebExams(override val data: DataEdudziennik,
|
class EdudziennikWebExams(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebExams"
|
const val TAG = "EdudziennikWebExams"
|
||||||
}
|
}
|
||||||
@ -44,7 +46,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
if (dateString.isBlank()) return@forEach
|
if (dateString.isBlank()) return@forEach
|
||||||
val date = Date.fromY_m_d(dateString)
|
val date = Date.fromY_m_d(dateString)
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date)
|
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
||||||
val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime
|
val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime
|
||||||
|
|
||||||
val eventTypeElement = examElement.child(3).child(0)
|
val eventTypeElement = examElement.child(3).child(0)
|
||||||
@ -54,17 +56,16 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
val eventType = data.getEventType(eventTypeId, eventTypeName)
|
val eventType = data.getEventType(eventTypeId, eventTypeName)
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
eventType.id.toInt(),
|
type = eventType.id,
|
||||||
false,
|
teacherId = -1,
|
||||||
-1,
|
subjectId = subject.id,
|
||||||
subject.id,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
@ -73,8 +74,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_EVENT,
|
Metadata.TYPE_EVENT,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
)))
|
)))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EXAMS)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,10 @@ import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
|
|||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebGetAnnouncement(
|
class EdudziennikWebGetAnnouncement(override val data: DataEdudziennik,
|
||||||
override val data: DataEdudziennik,
|
private val announcement: AnnouncementFull,
|
||||||
private val announcement: AnnouncementFull,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : EdudziennikWeb(data, null) {
|
||||||
) : EdudziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebGetAnnouncement"
|
const val TAG = "EdudziennikWebGetAnnouncement"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
||||||
|
|
||||||
|
import android.text.Html
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
|
|
||||||
|
class EdudziennikWebGetHomework(
|
||||||
|
override val data: DataEdudziennik,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : EdudziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "EdudziennikWebGetHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (event.attachmentNames.isNotNullNorEmpty()) {
|
||||||
|
val id = event.attachmentNames!![0]
|
||||||
|
|
||||||
|
webGet(TAG, "Homework/$id") { text ->
|
||||||
|
val description = Regexes.EDUDZIENNIK_HOMEWORK_DESCRIPTION.find(text)?.get(1)?.trim()
|
||||||
|
|
||||||
|
if (description != null) event.topic = Html.fromHtml(description).toString()
|
||||||
|
|
||||||
|
event.homeworkBody = ""
|
||||||
|
event.attachmentNames = null
|
||||||
|
|
||||||
|
data.eventList += event
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,24 +13,39 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_GRADES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_GRADES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebGrades(override val data: DataEdudziennik,
|
class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebGrades"
|
private const val TAG = "EdudziennikWebGrades"
|
||||||
}
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
private var requestSemester: Int? = null
|
||||||
webGet(TAG, data.studentEndpoint + "start") { text ->
|
|
||||||
val doc = Jsoup.parse(text)
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
|
||||||
|
getGrades()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getGrades() { data.profile?.also { profile ->
|
||||||
|
webGet(TAG, data.studentEndpoint + "start", semester = requestSemester) { text ->
|
||||||
|
val semester = requestSemester ?: data.currentSemester
|
||||||
|
|
||||||
|
val doc = Jsoup.parse(text)
|
||||||
val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
|
val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
|
||||||
|
|
||||||
subjects?.forEach { subjectElement ->
|
subjects?.forEach { subjectElement ->
|
||||||
@ -80,7 +95,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
val columnName = info.child(4).text().trim()
|
val columnName = info.child(4).text().trim()
|
||||||
val comment = info.ownText()
|
val comment = info.ownText()
|
||||||
|
|
||||||
val description = columnName + if (comment.isNotBlank()) " - $comment" else ""
|
val description = columnName + if (comment.isNotBlank()) " - $comment" else null
|
||||||
|
|
||||||
val teacherName = info.child(1).text()
|
val teacherName = info.child(1).text()
|
||||||
val teacher = data.getTeacherByLastFirst(teacherName)
|
val teacher = data.getTeacherByLastFirst(teacherName)
|
||||||
@ -99,20 +114,21 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
fullName,
|
name = name,
|
||||||
color,
|
type = gradeType,
|
||||||
description,
|
value = value,
|
||||||
name,
|
weight = if (gradeCountToAverage) weight else 0f,
|
||||||
value,
|
color = color,
|
||||||
if (gradeCountToAverage) weight else 0f,
|
category = fullName,
|
||||||
data.currentSemester,
|
description = description,
|
||||||
teacher.id,
|
comment = null,
|
||||||
subject.id
|
semester = semester,
|
||||||
).apply {
|
teacherId = teacher.id,
|
||||||
type = gradeType
|
subjectId = subject.id,
|
||||||
}
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -120,8 +136,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,23 +144,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
if (proposed != null && proposed.isNotBlank()) {
|
if (proposed != null && proposed.isNotBlank()) {
|
||||||
val proposedGradeObject = Grade(
|
val proposedGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
(-1 * subject.id) - 1,
|
id = (-1 * subject.id) - 1,
|
||||||
"",
|
name = proposed,
|
||||||
-1,
|
type = when (semester) {
|
||||||
"",
|
1 -> TYPE_SEMESTER1_PROPOSED
|
||||||
proposed,
|
else -> TYPE_SEMESTER2_PROPOSED
|
||||||
proposed.toFloatOrNull() ?: 0f,
|
},
|
||||||
0f,
|
value = proposed.toFloatOrNull() ?: 0f,
|
||||||
data.currentSemester,
|
weight = 0f,
|
||||||
-1,
|
color = -1,
|
||||||
subject.id
|
category = null,
|
||||||
).apply {
|
description = null,
|
||||||
type = when (semester) {
|
comment = null,
|
||||||
1 -> TYPE_SEMESTER1_PROPOSED
|
semester = semester,
|
||||||
else -> TYPE_SEMESTER2_PROPOSED
|
teacherId = -1,
|
||||||
}
|
subjectId = subject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(proposedGradeObject)
|
data.gradeList.add(proposedGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -153,8 +168,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
proposedGradeObject.id,
|
proposedGradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,23 +176,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
if (final != null && final.isNotBlank()) {
|
if (final != null && final.isNotBlank()) {
|
||||||
val finalGradeObject = Grade(
|
val finalGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
(-1 * subject.id) - 2,
|
id = (-1 * subject.id) - 2,
|
||||||
"",
|
name = final,
|
||||||
-1,
|
type = when (semester) {
|
||||||
"",
|
1 -> TYPE_SEMESTER1_FINAL
|
||||||
final,
|
else -> TYPE_SEMESTER2_FINAL
|
||||||
final.toFloatOrNull() ?: 0f,
|
},
|
||||||
0f,
|
value = final.toFloatOrNull() ?: 0f,
|
||||||
data.currentSemester,
|
weight = 0f,
|
||||||
-1,
|
color = -1,
|
||||||
subject.id
|
category = null,
|
||||||
).apply {
|
description = null,
|
||||||
type = when (semester) {
|
comment = null,
|
||||||
1 -> TYPE_SEMESTER1_FINAL
|
semester = semester,
|
||||||
else -> TYPE_SEMESTER2_FINAL
|
teacherId = -1,
|
||||||
}
|
subjectId = subject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(finalGradeObject)
|
data.gradeList.add(finalGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -186,8 +200,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
finalGradeObject.id,
|
finalGradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,12 +214,17 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
TYPE_SEMESTER1_FINAL,
|
TYPE_SEMESTER1_FINAL,
|
||||||
TYPE_SEMESTER2_FINAL
|
TYPE_SEMESTER2_FINAL
|
||||||
).map {
|
).map {
|
||||||
DataRemoveModel.Grades.semesterWithType(data.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(semester, it)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
||||||
onSuccess()
|
requestSemester = null
|
||||||
|
getGrades()
|
||||||
|
} else {
|
||||||
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
||||||
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebHomework(override val data: DataEdudziennik,
|
class EdudziennikWebHomework(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebHomework"
|
const val TAG = "EdudziennikWebHomework"
|
||||||
}
|
}
|
||||||
@ -31,8 +33,8 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
|
if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
|
||||||
doc.getElementsByTag("tr").forEach { homeworkElement ->
|
doc.getElementsByTag("tr").forEach { homeworkElement ->
|
||||||
val dateElement = homeworkElement.getElementsByClass("date").first().child(0)
|
val dateElement = homeworkElement.getElementsByClass("date").first().child(0)
|
||||||
val id = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1)?.crc32()
|
val idStr = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1) ?: return@forEach
|
||||||
?: return@forEach
|
val id = idStr.crc32()
|
||||||
val date = Date.fromY_m_d(dateElement.text())
|
val date = Date.fromY_m_d(dateElement.text())
|
||||||
|
|
||||||
val subjectElement = homeworkElement.child(1).child(0)
|
val subjectElement = homeworkElement.child(1).child(0)
|
||||||
@ -41,36 +43,36 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
val subjectName = subjectElement.text()
|
val subjectName = subjectElement.text()
|
||||||
val subject = data.getSubject(subjectId, subjectName)
|
val subject = data.getSubject(subjectId, subjectName)
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date)
|
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
||||||
val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime
|
val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime
|
||||||
|
|
||||||
val teacherName = homeworkElement.child(2).text()
|
val teacherName = homeworkElement.child(2).text()
|
||||||
val teacher = data.getTeacherByFirstLast(teacherName)
|
val teacher = data.getTeacherByFirstLast(teacherName)
|
||||||
|
|
||||||
val topic = homeworkElement.child(4).text()
|
val topic = homeworkElement.child(4).text()?.trim()
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
date,
|
date = date,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic ?: "",
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacher.id,
|
||||||
teacher.id,
|
subjectId = subject.id,
|
||||||
subject.id,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
eventObject.attachmentNames = mutableListOf(idStr)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_HOMEWORK,
|
Metadata.TYPE_HOMEWORK,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +80,7 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) }
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,15 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebLuckyNumber"
|
private const val TAG = "EdudziennikWebLuckyNumber"
|
||||||
}
|
}
|
||||||
@ -22,9 +24,9 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
|||||||
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
|
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
|
||||||
text.toIntOrNull()?.also { luckyNumber ->
|
text.toIntOrNull()?.also { luckyNumber ->
|
||||||
val luckyNumberObject = LuckyNumber(
|
val luckyNumberObject = LuckyNumber(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
Date.getToday(),
|
date = Date.getToday(),
|
||||||
luckyNumber
|
number = luckyNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
@ -33,13 +35,12 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_LUCKY_NUMBER,
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
luckyNumberObject.date.value.toLong(),
|
luckyNumberObject.date.value.toLong(),
|
||||||
true,
|
true,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) }
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,16 @@ import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_NOTE_ID
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebNotes(override val data: DataEdudziennik,
|
class EdudziennikWebNotes(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebNotes"
|
const val TAG = "EdudziennikWebNotes"
|
||||||
}
|
}
|
||||||
@ -39,12 +41,15 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
|
|||||||
val description = noteElement.child(3).text()
|
val description = noteElement.child(3).text()
|
||||||
|
|
||||||
val noticeObject = Notice(
|
val noticeObject = Notice(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
description,
|
type = Notice.TYPE_NEUTRAL,
|
||||||
data.currentSemester,
|
semester = profile.currentSemester,
|
||||||
Notice.TYPE_NEUTRAL,
|
text = description,
|
||||||
teacher.id
|
category = null,
|
||||||
|
points = null,
|
||||||
|
teacherId = teacher.id,
|
||||||
|
addedDate = addedDate
|
||||||
)
|
)
|
||||||
|
|
||||||
data.noticeList.add(noticeObject)
|
data.noticeList.add(noticeObject)
|
||||||
@ -53,13 +58,12 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_NOTICE,
|
Metadata.TYPE_NOTICE,
|
||||||
id,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) }
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,9 @@ import pl.szczodrzynski.edziennik.firstLettersName
|
|||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebStart(override val data: DataEdudziennik,
|
class EdudziennikWebStart(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebStart"
|
private const val TAG = "EdudziennikWebStart"
|
||||||
}
|
}
|
||||||
@ -29,7 +31,7 @@ class EdudziennikWebStart(override val data: DataEdudziennik,
|
|||||||
getSubjects(text)
|
getSubjects(text)
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_START)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.Edudzienni
|
|||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebTeachers"
|
private const val TAG = "EdudziennikWebTeachers"
|
||||||
}
|
}
|
||||||
@ -26,7 +28,7 @@ class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.singleOrNull
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
@ -24,7 +24,9 @@ import pl.szczodrzynski.edziennik.utils.models.Time
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebTimetable"
|
private const val TAG = "EdudziennikWebTimetable"
|
||||||
}
|
}
|
||||||
@ -122,8 +124,7 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|||||||
Metadata.TYPE_LESSON_CHANGE,
|
Metadata.TYPE_LESSON_CHANGE,
|
||||||
lessonObject.id,
|
lessonObject.id,
|
||||||
seen,
|
seen,
|
||||||
seen,
|
seen
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +143,7 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) }
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit
|
|||||||
private const val TAG = "EdudziennikFirstLogin"
|
private const val TAG = "EdudziennikFirstLogin"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val web = EdudziennikWeb(data)
|
private val web = EdudziennikWeb(data, null)
|
||||||
private val profileList = mutableListOf<Profile>()
|
private val profileList = mutableListOf<Profile>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -59,7 +59,7 @@ class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit
|
|||||||
profileList.add(profile)
|
profileList.add(profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore))
|
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|||||||
import pl.szczodrzynski.edziennik.getUnixDate
|
import pl.szczodrzynski.edziennik.getUnixDate
|
||||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -25,7 +24,7 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.app.cookieJar.clearForDomain("dziennikel.appspot.com")
|
data.app.cookieJar.clear("dziennikel.appspot.com")
|
||||||
if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
||||||
loginWithCredentials()
|
loginWithCredentials()
|
||||||
}
|
}
|
||||||
@ -60,9 +59,8 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
||||||
val sessionId = cookies.firstOrNull { it.name() == "sessionid" }?.value()
|
val sessionId = cookies["sessionid"]
|
||||||
val semester = cookies.firstOrNull { it.name() == "semester" }?.value()?.toIntOrNull()
|
|
||||||
|
|
||||||
if (sessionId == null) {
|
if (sessionId == null) {
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
||||||
@ -72,14 +70,6 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.webSessionId = sessionId
|
data.webSessionId = sessionId
|
||||||
|
|
||||||
if (data.profile != null && semester != null) {
|
|
||||||
data.currentSemester = semester
|
|
||||||
|
|
||||||
if (semester == 2 && data.profile.dateSemester2Start > Date.getToday())
|
|
||||||
data.profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
|
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-5-14
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.helper
|
||||||
|
|
||||||
|
import im.wangchao.mhttp.Request
|
||||||
|
import im.wangchao.mhttp.Response
|
||||||
|
import im.wangchao.mhttp.callback.FileCallbackHandler
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_FILE_DOWNLOAD
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.SYSTEM_USER_AGENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class DownloadAttachment(
|
||||||
|
fileUrl: String,
|
||||||
|
val onSuccess: (file: File) -> Unit,
|
||||||
|
val onProgress: (written: Long, total: Long) -> Unit,
|
||||||
|
val onError: (apiError: ApiError) -> Unit
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "DownloadAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val targetFile = Utils.getStorageDir()
|
||||||
|
|
||||||
|
val callback = object : FileCallbackHandler(targetFile) {
|
||||||
|
override fun onSuccess(file: File?, response: Response?) {
|
||||||
|
if (file == null) {
|
||||||
|
onError(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
onSuccess(file)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgress(bytesWritten: Long, bytesTotal: Long) {
|
||||||
|
try {
|
||||||
|
this@DownloadAttachment.onProgress(bytesWritten, bytesTotal)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||||
|
onError(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.builder()
|
||||||
|
.url(fileUrl)
|
||||||
|
.userAgent(SYSTEM_USER_AGENT)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.helper
|
||||||
|
|
||||||
|
import im.wangchao.mhttp.Request
|
||||||
|
import im.wangchao.mhttp.Response
|
||||||
|
import im.wangchao.mhttp.callback.FileCallbackHandler
|
||||||
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_ONEDRIVE_DOWNLOAD
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.SYSTEM_USER_AGENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class OneDriveDownloadAttachment(
|
||||||
|
app: App,
|
||||||
|
fileUrl: String,
|
||||||
|
val onSuccess: (file: File) -> Unit,
|
||||||
|
val onProgress: (written: Long, total: Long) -> Unit,
|
||||||
|
val onError: (apiError: ApiError) -> Unit
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "OneDriveDownloadAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
Request.builder()
|
||||||
|
.url(fileUrl)
|
||||||
|
.userAgent(SYSTEM_USER_AGENT)
|
||||||
|
.withClient(app.httpLazy)
|
||||||
|
.callback(object : TextCallbackHandler() {
|
||||||
|
override fun onSuccess(text: String, response: Response) {
|
||||||
|
val location = response.headers().get("Location")
|
||||||
|
// https://onedrive.live.com/redir?resid=D75496A2EB87531C!706&authkey=!ABjZeh3pHMqj11Q
|
||||||
|
if (location?.contains("onedrive.live.com/redir?resid=") != true) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withApiResponse(text)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val url = location
|
||||||
|
.replace("onedrive.live.com/redir?resid=", "storage.live.com/items/")
|
||||||
|
.replace("?", "&")
|
||||||
|
.replaceFirst("&", "?")
|
||||||
|
downloadFile(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response, throwable: Throwable) {
|
||||||
|
onError(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadFile(url: String) {
|
||||||
|
val targetFile = Utils.getStorageDir()
|
||||||
|
|
||||||
|
val callback = object : FileCallbackHandler(targetFile) {
|
||||||
|
override fun onSuccess(file: File?, response: Response?) {
|
||||||
|
if (file == null) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
onSuccess(file)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgress(bytesWritten: Long, bytesTotal: Long) {
|
||||||
|
try {
|
||||||
|
this@OneDriveDownloadAttachment.onProgress(bytesWritten, bytesTotal)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
onError(ApiError(TAG, ERROR_ONEDRIVE_DOWNLOAD)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||||
|
onError(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withResponse(response)
|
||||||
|
.withThrowable(throwable))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.builder()
|
||||||
|
.url(url)
|
||||||
|
.userAgent(SYSTEM_USER_AGENT)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
||||||
|
|
||||||
import androidx.core.util.set
|
import androidx.core.util.set
|
||||||
import okhttp3.Cookie
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_API
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_API
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_WEB
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_WEB
|
||||||
@ -24,18 +23,8 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
|
|||||||
loginMethods.clear()
|
loginMethods.clear()
|
||||||
if (isWebLoginValid()) {
|
if (isWebLoginValid()) {
|
||||||
loginMethods += LOGIN_METHOD_IDZIENNIK_WEB
|
loginMethods += LOGIN_METHOD_IDZIENNIK_WEB
|
||||||
app.cookieJar.saveFromResponse(null, listOf(
|
app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", webSessionId)
|
||||||
Cookie.Builder()
|
app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", webAuth)
|
||||||
.name("ASP.NET_SessionId_iDziennik")
|
|
||||||
.value(webSessionId!!)
|
|
||||||
.domain("iuczniowie.progman.pl")
|
|
||||||
.secure().httpOnly().build(),
|
|
||||||
Cookie.Builder()
|
|
||||||
.name(".ASPXAUTH")
|
|
||||||
.value(webAuth!!)
|
|
||||||
.domain("iuczniowie.progman.pl")
|
|
||||||
.secure().httpOnly().build()
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
if (isApiLoginValid())
|
if (isApiLoginValid())
|
||||||
loginMethods += LOGIN_METHOD_IDZIENNIK_API
|
loginMethods += LOGIN_METHOD_IDZIENNIK_API
|
||||||
@ -81,6 +70,11 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
|
|||||||
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
||||||
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
||||||
|
|
||||||
|
private var mWebSelectedRegister: Int? = null
|
||||||
|
var webSelectedRegister: Int
|
||||||
|
get() { mWebSelectedRegister = mWebSelectedRegister ?: loginStore.getLoginData("webSelectedRegister", 0); return mWebSelectedRegister ?: 0 }
|
||||||
|
set(value) { loginStore.putLoginData("webSelectedRegister", value); mWebSelectedRegister = value }
|
||||||
|
|
||||||
/* _
|
/* _
|
||||||
/\ (_)
|
/\ (_)
|
||||||
/ \ _ __ _
|
/ \ _ __ _
|
||||||
|
@ -8,21 +8,16 @@ import com.google.gson.JsonObject
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetAttachment
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebGetRecipientList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSendMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin.IdziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin.IdziennikFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -43,9 +38,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -56,9 +49,9 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId)
|
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +98,17 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
override fun markAllAnnouncementsAsRead() {}
|
override fun markAllAnnouncementsAsRead() {}
|
||||||
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
||||||
IdziennikWebGetAttachment(data, message, attachmentId, attachmentName) {
|
if (owner is Message) {
|
||||||
completed()
|
IdziennikWebGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (owner is Event) {
|
||||||
|
IdziennikWebGetHomeworkAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +121,14 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
||||||
|
IdziennikWebGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { IdziennikFirstLogin(data) { completed() } }
|
override fun firstLogin() { IdziennikFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
|
@ -18,7 +18,7 @@ import pl.szczodrzynski.edziennik.getString
|
|||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
|
||||||
open class IdziennikApi(open val data: DataIdziennik) {
|
open class IdziennikApi(open val data: DataIdziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikApi"
|
const val TAG = "IdziennikApi"
|
||||||
}
|
}
|
||||||
|
@ -30,60 +30,62 @@ class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useEndpoint(data.targetEndpointIds.removeAt(0)) {
|
val id = data.targetEndpointIds.firstKey()
|
||||||
|
val lastSync = data.targetEndpointIds.remove(id)
|
||||||
|
useEndpoint(id, lastSync) { endpointId ->
|
||||||
data.progress(data.progressStep)
|
data.progress(data.progressStep)
|
||||||
nextEndpoint(onSuccess)
|
nextEndpoint(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
|
ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
||||||
IdziennikWebTimetable(data, onSuccess)
|
IdziennikWebTimetable(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_GRADES -> {
|
ENDPOINT_IDZIENNIK_WEB_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
IdziennikWebGrades(data, onSuccess)
|
IdziennikWebGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES -> {
|
ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
||||||
IdziennikWebProposedGrades(data, onSuccess)
|
IdziennikWebProposedGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_EXAMS -> {
|
ENDPOINT_IDZIENNIK_WEB_EXAMS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
||||||
IdziennikWebExams(data, onSuccess)
|
IdziennikWebExams(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_HOMEWORK -> {
|
ENDPOINT_IDZIENNIK_WEB_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
IdziennikWebHomework(data, onSuccess)
|
IdziennikWebHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_NOTICES -> {
|
ENDPOINT_IDZIENNIK_WEB_NOTICES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
IdziennikWebNotices(data, onSuccess)
|
IdziennikWebNotices(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
||||||
IdziennikWebAnnouncements(data, onSuccess)
|
IdziennikWebAnnouncements(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_ATTENDANCE -> {
|
ENDPOINT_IDZIENNIK_WEB_ATTENDANCE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
IdziennikWebAttendance(data, onSuccess)
|
IdziennikWebAttendance(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER -> {
|
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
IdziennikApiCurrentRegister(data, onSuccess)
|
IdziennikApiCurrentRegister(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX -> {
|
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
||||||
IdziennikApiMessagesInbox(data, onSuccess)
|
IdziennikApiMessagesInbox(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT -> {
|
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
||||||
IdziennikApiMessagesSent(data, onSuccess)
|
IdziennikApiMessagesSent(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
else -> onSuccess()
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,14 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSwitchRegister
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||||
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
||||||
|
|
||||||
open class IdziennikWeb(open val data: DataIdziennik) {
|
open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWeb"
|
const val TAG = "IdziennikWeb"
|
||||||
}
|
}
|
||||||
@ -48,6 +49,17 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response?.code() == HTTP_INTERNAL_ERROR && endpoint == IDZIENNIK_WEB_GRADES) {
|
||||||
|
// special override for accounts where displaying grades
|
||||||
|
// for another student requires switching it manually
|
||||||
|
if (data.registerId != data.webSelectedRegister) {
|
||||||
|
IdziennikWebSwitchRegister(data, data.registerId) {
|
||||||
|
webApiGet(tag, endpoint, parameters, onSuccess)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
||||||
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
||||||
@ -115,7 +127,7 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, onSuccess: (text: String) -> Unit) {
|
fun webGet(tag: String, endpoint: String, parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) {
|
||||||
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
@ -160,7 +172,14 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
Request.builder()
|
Request.builder()
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
.userAgent(IDZIENNIK_USER_AGENT)
|
||||||
.get()
|
.apply {
|
||||||
|
if (parameters.isEmpty()) get()
|
||||||
|
else post()
|
||||||
|
|
||||||
|
parameters.map { (name, value) ->
|
||||||
|
addParameter(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
@ -210,6 +229,7 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
.apply {
|
.apply {
|
||||||
parameters.forEach { (k, v) -> addParameter(k, v) }
|
parameters.forEach { (k, v) -> addParameter(k, v) }
|
||||||
}
|
}
|
||||||
|
.contentType("application/x-www-form-urlencoded")
|
||||||
.post()
|
.post()
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
|
@ -19,7 +19,9 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiCurrentRegister"
|
private const val TAG = "IdziennikApiCurrentRegister"
|
||||||
}
|
}
|
||||||
@ -27,7 +29,7 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_CURRENT_REGISTER) { json ->
|
apiGet(TAG, IDZIENNIK_API_CURRENT_REGISTER) { json ->
|
||||||
if (json !is JsonObject) {
|
if (json !is JsonObject) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +68,9 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
|
|
||||||
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
val luckyNumberObject = LuckyNumber(
|
||||||
data.profileId,
|
profileId = data.profileId,
|
||||||
Date.getToday(),
|
date = luckyNumberDate,
|
||||||
luckyNumber
|
number = luckyNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
@ -78,14 +80,13 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_LUCKY_NUMBER,
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
luckyNumberObject.date.value.toLong(),
|
luckyNumberObject.date.value.toLong(),
|
||||||
true,
|
true,
|
||||||
data.profile?.empty ?: false,
|
data.profile?.empty ?: false
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER, syncAt = nextSync)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER, syncAt = nextSync)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,18 @@ import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_API_MESSAGES_INBOX
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.getBoolean
|
import pl.szczodrzynski.edziennik.getBoolean
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiMessagesInbox"
|
private const val TAG = "IdziennikApiMessagesInbox"
|
||||||
}
|
}
|
||||||
@ -31,15 +29,15 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_INBOX) { json ->
|
apiGet(TAG, IDZIENNIK_API_MESSAGES_INBOX) { json ->
|
||||||
if (json !is JsonArray) {
|
if (json !is JsonArray) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
json.asJsonObjectList()?.forEach { jMessage ->
|
json.asJsonObjectList().forEach { jMessage ->
|
||||||
val subject = jMessage.getString("tytul")
|
val subject = jMessage.getString("tytul") ?: ""
|
||||||
if (subject?.contains("(") == true && subject.startsWith("iDziennik - "))
|
if (subject.contains("(") && subject.startsWith("iDziennik - "))
|
||||||
return@forEach
|
return@forEach
|
||||||
if (subject?.startsWith("Uwaga dla ucznia (klasa:") == true)
|
if (subject.startsWith("Uwaga dla ucznia (klasa:"))
|
||||||
return@forEach
|
return@forEach
|
||||||
|
|
||||||
val messageIdStr = jMessage.getString("id")
|
val messageIdStr = jMessage.getString("id")
|
||||||
@ -66,13 +64,13 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
messageId,
|
id = messageId,
|
||||||
subject,
|
type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
||||||
body,
|
subject = subject,
|
||||||
if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
body = body,
|
||||||
rTeacher.id,
|
senderId = rTeacher.id,
|
||||||
-1
|
addedDate = sentDate
|
||||||
)
|
)
|
||||||
|
|
||||||
val messageRecipient = MessageRecipient(
|
val messageRecipient = MessageRecipient(
|
||||||
@ -83,20 +81,19 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
/*messageId*/ messageId
|
/*messageId*/ messageId
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.messageRecipientList.add(messageRecipient)
|
data.messageRecipientList.add(messageRecipient)
|
||||||
data.setSeenMetadataList.add(Metadata(
|
data.setSeenMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_MESSAGE,
|
Metadata.TYPE_MESSAGE,
|
||||||
message.id,
|
message.id,
|
||||||
readDate > 0,
|
readDate > 0,
|
||||||
readDate > 0 || profile?.empty ?: false,
|
readDate > 0 || profile?.empty ?: false
|
||||||
sentDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiMessagesSent"
|
private const val TAG = "IdziennikApiMessagesSent"
|
||||||
}
|
}
|
||||||
@ -28,7 +30,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_SENT) { json ->
|
apiGet(TAG, IDZIENNIK_API_MESSAGES_SENT) { json ->
|
||||||
if (json !is JsonArray) {
|
if (json !is JsonArray) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,13 +46,13 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
||||||
|
|
||||||
val message = Message(
|
val message = Message(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
messageId,
|
id = messageId,
|
||||||
subject,
|
type = TYPE_SENT,
|
||||||
body,
|
subject = subject,
|
||||||
TYPE_SENT,
|
body = body,
|
||||||
-1,
|
senderId = null,
|
||||||
-1
|
addedDate = sentDate
|
||||||
)
|
)
|
||||||
|
|
||||||
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
||||||
@ -74,12 +76,12 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
data.messageRecipientIgnoreList.add(messageRecipient)
|
data.messageRecipientIgnoreList.add(messageRecipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.messageIgnoreList.add(message)
|
data.messageList.add(message)
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,17 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getLong
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebAnnouncements"
|
private const val TAG = "IdziennikWebAnnouncements"
|
||||||
}
|
}
|
||||||
@ -41,21 +45,21 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
|||||||
for (jAnnouncementEl in json.getAsJsonArray("ListK")) {
|
for (jAnnouncementEl in json.getAsJsonArray("ListK")) {
|
||||||
val jAnnouncement = jAnnouncementEl.asJsonObject
|
val jAnnouncement = jAnnouncementEl.asJsonObject
|
||||||
// jAnnouncement
|
// jAnnouncement
|
||||||
val announcementId = jAnnouncement.get("Id").asLong
|
val announcementId = jAnnouncement.getLong("Id") ?: -1
|
||||||
|
|
||||||
val rTeacher = data.getTeacherByFirstLast(jAnnouncement.get("Autor").asString)
|
val rTeacher = data.getTeacherByFirstLast(jAnnouncement.getString("Autor") ?: "")
|
||||||
val addedDate = java.lang.Long.parseLong(jAnnouncement.get("DataDodania").asString.replace("[^\\d]".toRegex(), ""))
|
val addedDate = jAnnouncement.getString("DataDodania")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull() ?: System.currentTimeMillis()
|
||||||
val startDate = Date.fromMillis(java.lang.Long.parseLong(jAnnouncement.get("DataWydarzenia").asString.replace("[^\\d]".toRegex(), "")))
|
val startDate = jAnnouncement.getString("DataWydarzenia")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull()?.let { Date.fromMillis(it) }
|
||||||
|
|
||||||
val announcementObject = Announcement(
|
val announcementObject = Announcement(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
announcementId,
|
id = announcementId,
|
||||||
jAnnouncement.get("Temat").asString,
|
subject = jAnnouncement.get("Temat").asString,
|
||||||
jAnnouncement.get("Tresc").asString,
|
text = jAnnouncement.get("Tresc").asString,
|
||||||
startDate,
|
startDate = startDate,
|
||||||
null,
|
endDate = null,
|
||||||
rTeacher.id,
|
teacherId = rTeacher.id,
|
||||||
null
|
addedDate = addedDate
|
||||||
)
|
)
|
||||||
data.announcementList.add(announcementObject)
|
data.announcementList.add(announcementObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -63,13 +67,12 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_ANNOUNCEMENT,
|
Metadata.TYPE_ANNOUNCEMENT,
|
||||||
announcementObject.id,
|
announcementObject.id,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,33 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ATTENDANCE
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ATTENDANCE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ATTENDANCE
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ATTENDANCE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT_CUSTOM
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
import pl.szczodrzynski.edziennik.getInt
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class IdziennikWebAttendance(override val data: DataIdziennik,
|
class IdziennikWebAttendance(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebAttendance"
|
private const val TAG = "IdziennikWebAttendance"
|
||||||
}
|
}
|
||||||
@ -49,71 +59,97 @@ class IdziennikWebAttendance(override val data: DataIdziennik,
|
|||||||
for (jAttendanceEl in json.getAsJsonArray("Obecnosci")) {
|
for (jAttendanceEl in json.getAsJsonArray("Obecnosci")) {
|
||||||
val jAttendance = jAttendanceEl.asJsonObject
|
val jAttendance = jAttendanceEl.asJsonObject
|
||||||
// jAttendance
|
// jAttendance
|
||||||
val attendanceTypeIdziennik = jAttendance.get("TypObecnosci").asInt
|
val type = jAttendance.get("TypObecnosci").asInt
|
||||||
if (attendanceTypeIdziennik == 5 || attendanceTypeIdziennik == 7)
|
|
||||||
continue
|
// skip "zajęcia nie odbyły się" and "Ferie"
|
||||||
val attendanceDate = Date.fromY_m_d(jAttendance.get("Data").asString)
|
if (type == 5 || type == 7)
|
||||||
val attendanceTime = Time.fromH_m(jAttendance.get("OdDoGodziny").asString)
|
|
||||||
if (attendanceDate.combineWith(attendanceTime) > System.currentTimeMillis())
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val attendanceId = jAttendance.get("IdLesson").asString.crc16().toLong()
|
val date = Date.fromY_m_d(jAttendance.get("Data").asString)
|
||||||
|
val time = Time.fromH_m(jAttendance.get("OdDoGodziny").asString)
|
||||||
|
if (date.combineWith(time) > System.currentTimeMillis())
|
||||||
|
continue
|
||||||
|
|
||||||
|
val id = jAttendance.get("IdLesson").asString.crc16().toLong()
|
||||||
val rSubject = data.getSubject(jAttendance.get("Przedmiot").asString, jAttendance.get("IdPrzedmiot").asLong, "")
|
val rSubject = data.getSubject(jAttendance.get("Przedmiot").asString, jAttendance.get("IdPrzedmiot").asLong, "")
|
||||||
val rTeacher = data.getTeacherByFDotSpaceLast(jAttendance.get("PrzedmiotNauczyciel").asString)
|
val rTeacher = data.getTeacherByFDotSpaceLast(jAttendance.get("PrzedmiotNauczyciel").asString)
|
||||||
|
|
||||||
var attendanceName = "obecność"
|
var baseType = TYPE_UNKNOWN
|
||||||
var attendanceType = Attendance.TYPE_CUSTOM
|
var typeName = "nieznany rodzaj"
|
||||||
|
var typeSymbol: String? = null
|
||||||
|
var typeColor: Long? = null
|
||||||
|
|
||||||
when (attendanceTypeIdziennik) {
|
/* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosciUcznia_lmt637231494660000000.js */
|
||||||
1 /* nieobecność usprawiedliwiona */ -> {
|
/* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosci_lmt637231494660000000.css */
|
||||||
attendanceName = "nieobecność usprawiedliwiona"
|
when (type) {
|
||||||
attendanceType = TYPE_ABSENT_EXCUSED
|
1 -> {
|
||||||
|
baseType = TYPE_ABSENT_EXCUSED
|
||||||
|
typeName = "nieobecność usprawiedliwiona"
|
||||||
|
typeColor = 0xffffe099
|
||||||
}
|
}
|
||||||
2 /* spóźnienie */ -> {
|
2 -> {
|
||||||
attendanceName = "spóźnienie"
|
baseType = TYPE_BELATED
|
||||||
attendanceType = TYPE_BELATED
|
typeName = "spóźnienie"
|
||||||
|
typeColor = 0xffffffaa
|
||||||
}
|
}
|
||||||
3 /* nieobecność nieusprawiedliwiona */ -> {
|
3 -> {
|
||||||
attendanceName = "nieobecność nieusprawiedliwiona"
|
baseType = TYPE_ABSENT
|
||||||
attendanceType = TYPE_ABSENT
|
typeName = "nieobecność nieusprawiedliwiona"
|
||||||
|
typeColor = 0xffffad99
|
||||||
}
|
}
|
||||||
4 /* zwolnienie */, 9 /* zwolniony / obecny */ -> {
|
4, 9 -> {
|
||||||
attendanceType = TYPE_RELEASED
|
baseType = TYPE_RELEASED
|
||||||
if (attendanceTypeIdziennik == 4)
|
if (type == 4) {
|
||||||
attendanceName = "zwolnienie"
|
typeName = "zwolnienie"
|
||||||
if (attendanceTypeIdziennik == 9)
|
typeColor = 0xffa8beff
|
||||||
attendanceName = "zwolnienie / obecność"
|
}
|
||||||
|
if (type == 9) {
|
||||||
|
typeName = "zwolniony / obecny"
|
||||||
|
typeSymbol = "zb"
|
||||||
|
typeColor = 0xffff69b4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0 /* obecny */, 8 /* Wycieczka */ -> {
|
8 -> {
|
||||||
attendanceType = TYPE_PRESENT
|
baseType = TYPE_PRESENT_CUSTOM
|
||||||
if (attendanceTypeIdziennik == 8)
|
typeName = "wycieczka"
|
||||||
attendanceName = "wycieczka"
|
typeSymbol = "w"
|
||||||
|
typeColor = null
|
||||||
|
}
|
||||||
|
0 -> {
|
||||||
|
baseType = TYPE_PRESENT
|
||||||
|
typeName = "obecny"
|
||||||
|
typeColor = 0xffccffcc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val semester = profile?.dateToSemester(attendanceDate) ?: 1
|
val semester = profile?.dateToSemester(date) ?: 1
|
||||||
|
|
||||||
val attendanceObject = Attendance(
|
val attendanceObject = Attendance(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
attendanceId,
|
id = id,
|
||||||
rTeacher.id,
|
baseType = baseType,
|
||||||
rSubject.id,
|
typeName = typeName,
|
||||||
semester,
|
typeShort = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
|
||||||
attendanceName,
|
typeSymbol = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
|
||||||
attendanceDate,
|
typeColor = typeColor?.toInt(),
|
||||||
attendanceTime,
|
date = date,
|
||||||
attendanceType
|
startTime = time,
|
||||||
)
|
semester = semester,
|
||||||
|
teacherId = rTeacher.id,
|
||||||
|
subjectId = rSubject.id
|
||||||
|
).also {
|
||||||
|
it.lessonTopic = jAttendance.getString("PrzedmiotTemat")
|
||||||
|
it.lessonNumber = jAttendance.getInt("Godzina")
|
||||||
|
}
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
if (attendanceObject.type != TYPE_PRESENT) {
|
if (attendanceObject.baseType != TYPE_PRESENT) {
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_ATTENDANCE,
|
Metadata.TYPE_ATTENDANCE,
|
||||||
attendanceObject.id,
|
attendanceObject.id,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +173,7 @@ class IdziennikWebAttendance(override val data: DataIdziennik,
|
|||||||
getAttendance()
|
getAttendance()
|
||||||
} else {
|
} else {
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class IdziennikWebExams(override val data: DataIdziennik,
|
class IdziennikWebExams(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebExams"
|
private const val TAG = "IdziennikWebExams"
|
||||||
}
|
}
|
||||||
@ -63,28 +66,30 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
||||||
val teacherName = exam.getString("wpisal") ?: return@forEach
|
val teacherName = exam.getString("wpisal") ?: return@forEach
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
||||||
val topic = exam.getString("zakres") ?: ""
|
val topic = exam.getString("zakres")?.trim() ?: ""
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate)
|
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, examDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
|
|
||||||
val eventType = when (exam.getString("rodzaj")) {
|
val eventType = when (exam.getString("rodzaj")?.toLowerCase(Locale.getDefault())) {
|
||||||
"sprawdzian/praca klasowa" -> Event.TYPE_EXAM
|
"sprawdzian/praca klasowa",
|
||||||
else -> Event.TYPE_SHORT_QUIZ
|
"sprawdzian",
|
||||||
|
"praca klasowa" -> Event.TYPE_EXAM
|
||||||
|
"kartkówka" -> Event.TYPE_SHORT_QUIZ
|
||||||
|
else -> Event.TYPE_EXAM
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
examDate,
|
date = examDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
eventType,
|
type = eventType,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = data.teamClass?.id ?: -1
|
||||||
data.teamClass?.id ?: -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
@ -93,8 +98,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_EVENT,
|
Metadata.TYPE_EVENT,
|
||||||
eventObject.id,
|
eventObject.id,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +120,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_EXAMS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,19 @@ import pl.szczodrzynski.edziennik.get
|
|||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IdziennikWebGetAttachment(
|
class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik, val message: Message, val attachmentId: Long,
|
val owner: Any,
|
||||||
val attachmentName: String, val onSuccess: () -> Unit
|
val attachmentId: Long,
|
||||||
) : IdziennikWeb(data) {
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWebGetAttachment"
|
const val TAG = "IdziennikWebGetAttachment"
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
val message = owner as Message
|
||||||
|
|
||||||
val messageId = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex().find(message.body ?: "")?.get(2) ?: -1
|
val messageId = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex().find(message.body ?: "")?.get(2) ?: -1
|
||||||
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
||||||
|
|
||||||
@ -32,29 +36,29 @@ class IdziennikWebGetAttachment(
|
|||||||
), { file ->
|
), { file ->
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_FINISHED,
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
file.absolutePath
|
file.absolutePath
|
||||||
)
|
)
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.messageId}_${event.attachmentId}")
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
|
||||||
}) { written, _ ->
|
}) { written, _ ->
|
||||||
val event = AttachmentGetEvent(
|
val event = AttachmentGetEvent(
|
||||||
profileId,
|
profileId,
|
||||||
message.id,
|
owner,
|
||||||
attachmentId,
|
attachmentId,
|
||||||
AttachmentGetEvent.TYPE_PROGRESS,
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
bytesWritten = written
|
bytesWritten = written
|
||||||
)
|
)
|
||||||
|
|
||||||
EventBus.getDefault().post(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.getBoolean
|
||||||
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
|
||||||
|
class IdziennikWebGetHomework(override val data: DataIdziennik,
|
||||||
|
val event: EventFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "IdziennikWebGetHomework"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
webApiGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK, mapOf(
|
||||||
|
"idP" to data.registerId,
|
||||||
|
"idPD" to event.id
|
||||||
|
)) { result ->
|
||||||
|
val json = result.getJsonObject("d") ?: run {
|
||||||
|
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
||||||
|
.withApiResponse(result))
|
||||||
|
return@webApiGet
|
||||||
|
}
|
||||||
|
|
||||||
|
val homework = json.getJsonObject("praca") ?: return@webApiGet
|
||||||
|
|
||||||
|
if (homework.getBoolean("zalacznik", false)) {
|
||||||
|
event.attachmentIds = mutableListOf(event.id)
|
||||||
|
event.attachmentNames = mutableListOf("Załącznik do zadania")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.attachmentIds = mutableListOf()
|
||||||
|
event.attachmentNames = mutableListOf()
|
||||||
|
}
|
||||||
|
event.homeworkBody = homework.getString("tresc")
|
||||||
|
|
||||||
|
data.eventList.add(event)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(EventGetEvent(event))
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.set
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class IdziennikWebGetHomeworkAttachment(override val data: DataIdziennik,
|
||||||
|
val owner: Any,
|
||||||
|
val attachmentId: Long,
|
||||||
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "IdziennikWebGetHomeworkAttachment"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val homework = owner as Event
|
||||||
|
|
||||||
|
/*val request = Request.Builder()
|
||||||
|
.url("")
|
||||||
|
.build()
|
||||||
|
data.app.http.newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||||
|
.withThrowable(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
val filename = response.header("content-disposition")?.substringAfter("\"")?.substringBeforeLast("\"")
|
||||||
|
|
||||||
|
val file: File = File(Utils.getStorageDir(), filename)
|
||||||
|
val sink = file.sink().buffer()
|
||||||
|
response.body()?.source()?.let {
|
||||||
|
sink.writeAll(it)
|
||||||
|
}
|
||||||
|
sink.close()
|
||||||
|
}
|
||||||
|
})*/
|
||||||
|
|
||||||
|
webGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT) { text ->
|
||||||
|
val hiddenFields = JsonObject()
|
||||||
|
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
||||||
|
hiddenFields[it[1]] = it[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
webGetFile(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT, Utils.getStorageDir(), mapOf(
|
||||||
|
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
||||||
|
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
||||||
|
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
||||||
|
"__EVENTTARGET" to "ctl00\$cphContent\$bt_pobraniePliku",
|
||||||
|
"ctl00\$dxComboUczniowie" to data.registerId,
|
||||||
|
"ctl00\$cphContent\$idPracyDomowej" to attachmentId
|
||||||
|
), { file ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_FINISHED,
|
||||||
|
file.absolutePath
|
||||||
|
)
|
||||||
|
|
||||||
|
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
||||||
|
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
||||||
|
|
||||||
|
homework.attachmentNames = mutableListOf(file.name)
|
||||||
|
data.eventList.add(homework)
|
||||||
|
data.eventListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
onSuccess()
|
||||||
|
|
||||||
|
}) { written, _ ->
|
||||||
|
val event = AttachmentGetEvent(
|
||||||
|
profileId,
|
||||||
|
owner,
|
||||||
|
attachmentId,
|
||||||
|
AttachmentGetEvent.TYPE_PROGRESS,
|
||||||
|
bytesWritten = written
|
||||||
|
)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,18 +10,17 @@ import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_MESSAGE
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebGetMessage(
|
class IdziennikWebGetMessage(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik,
|
private val message: MessageFull,
|
||||||
private val message: MessageFull,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : IdziennikWeb(data, null) {
|
||||||
) : IdziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWebGetMessage"
|
const val TAG = "IdziennikWebGetMessage"
|
||||||
}
|
}
|
||||||
@ -51,7 +50,11 @@ class IdziennikWebGetMessage(
|
|||||||
message.recipients?.clear()
|
message.recipients?.clear()
|
||||||
when (message.type) {
|
when (message.type) {
|
||||||
TYPE_RECEIVED -> {
|
TYPE_RECEIVED -> {
|
||||||
val recipientObject = MessageRecipientFull(profileId, -1, message.id)
|
val recipientObject = MessageRecipientFull(
|
||||||
|
profileId = profileId,
|
||||||
|
id = -1,
|
||||||
|
messageId = message.id
|
||||||
|
)
|
||||||
|
|
||||||
val readDateString = it.getString("DataOdczytania")
|
val readDateString = it.getString("DataOdczytania")
|
||||||
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
||||||
@ -68,7 +71,11 @@ class IdziennikWebGetMessage(
|
|||||||
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
||||||
val teacher = data.getTeacherByLastFirst(recipientName)
|
val teacher = data.getTeacherByLastFirst(recipientName)
|
||||||
|
|
||||||
val recipientObject = MessageRecipientFull(profileId, teacher.id, message.id)
|
val recipientObject = MessageRecipientFull(
|
||||||
|
profileId = profileId,
|
||||||
|
id = teacher.id,
|
||||||
|
messageId = message.id
|
||||||
|
)
|
||||||
|
|
||||||
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
||||||
recipientObject.fullName = teacher.fullName
|
recipientObject.fullName = teacher.fullName
|
||||||
@ -87,14 +94,14 @@ class IdziennikWebGetMessage(
|
|||||||
Metadata.TYPE_MESSAGE,
|
Metadata.TYPE_MESSAGE,
|
||||||
message.id,
|
message.id,
|
||||||
message.seen,
|
message.seen,
|
||||||
message.notified,
|
message.notified
|
||||||
message.addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageList.add(message)
|
||||||
|
data.messageListReplace = true
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,9 @@ import pl.szczodrzynski.edziennik.data.api.events.RecipientListGetEvent
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
|
||||||
class IdziennikWebGetRecipientList(
|
class IdziennikWebGetRecipientList(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik, val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebGetRecipientList"
|
private const val TAG = "IdziennikWebGetRecipientList"
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebGrades(override val data: DataIdziennik,
|
class IdziennikWebGrades(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebGrades"
|
private const val TAG = "IdziennikWebGrades"
|
||||||
}
|
}
|
||||||
@ -60,18 +63,24 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
colorInt = Color.parseColor("#$gradeColor")
|
colorInt = Color.parseColor("#$gradeColor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val addedDate = grade.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
category,
|
name = name,
|
||||||
colorInt,
|
type = TYPE_NORMAL,
|
||||||
"",
|
value = value,
|
||||||
name,
|
weight = weight,
|
||||||
value,
|
color = colorInt,
|
||||||
weight,
|
category = category,
|
||||||
semester,
|
description = null,
|
||||||
teacher.id,
|
comment = null,
|
||||||
subject.id)
|
semester = semester,
|
||||||
|
teacherId = teacher.id,
|
||||||
|
subjectId = subject.id,
|
||||||
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
when (grade.getInt("Typ")) {
|
when (grade.getInt("Typ")) {
|
||||||
0 -> {
|
0 -> {
|
||||||
@ -89,30 +98,39 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
count += weight
|
count += weight
|
||||||
}
|
}
|
||||||
|
|
||||||
val historyObject = Grade(
|
val historyColor = historyItem.getString("Kolor") ?: ""
|
||||||
profileId,
|
colorInt = 0xff2196f3.toInt()
|
||||||
gradeObject.id * -1,
|
if (historyColor.isNotEmpty()) {
|
||||||
historyItem.get("Kategoria").asString,
|
colorInt = Color.parseColor("#$historyColor")
|
||||||
Color.parseColor("#" + historyItem.get("Kolor").asString),
|
}
|
||||||
historyItem.get("Uzasadnienie").asString,
|
|
||||||
historyItem.get("Ocena").asString,
|
|
||||||
value,
|
|
||||||
if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
|
||||||
historyItem.get("Semestr").asInt,
|
|
||||||
teacher.id,
|
|
||||||
subject.id)
|
|
||||||
historyObject.parentId = gradeObject.id
|
|
||||||
|
|
||||||
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
||||||
|
|
||||||
|
val historyObject = Grade(
|
||||||
|
profileId = profileId,
|
||||||
|
id = gradeObject.id * -1,
|
||||||
|
name = historyItem.getString("Ocena") ?: "",
|
||||||
|
type = TYPE_NORMAL,
|
||||||
|
value = value,
|
||||||
|
weight = if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
||||||
|
color = colorInt,
|
||||||
|
category = historyItem.getString("Kategoria"),
|
||||||
|
description = historyItem.getString("Uzasadnienie"),
|
||||||
|
comment = null,
|
||||||
|
semester = historyItem.getInt("Semestr") ?: 1,
|
||||||
|
teacherId = teacher.id,
|
||||||
|
subjectId = subject.id,
|
||||||
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
historyObject.parentId = gradeObject.id
|
||||||
|
|
||||||
data.gradeList.add(historyObject)
|
data.gradeList.add(historyObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
historyObject.id,
|
historyObject.id,
|
||||||
true,
|
true,
|
||||||
true,
|
true
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
// update the current grade's value with an average of all historical grades and itself
|
// update the current grade's value with an average of all historical grades and itself
|
||||||
@ -134,8 +152,6 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val addedDate = grade.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(
|
data.metadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
@ -143,8 +159,7 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
id,
|
id,
|
||||||
data.profile.empty,
|
data.profile.empty,
|
||||||
data.profile.empty,
|
data.profile.empty
|
||||||
addedDate
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +172,7 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
||||||
})
|
})
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebHomework(override val data: DataIdziennik,
|
class IdziennikWebHomework(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebHomework"
|
private const val TAG = "IdziennikWebHomework"
|
||||||
}
|
}
|
||||||
@ -50,13 +52,14 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { homework ->
|
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { homework ->
|
||||||
val id = homework.getLong("_recordId") ?: return@forEach
|
val id = homework.getLong("_recordId") ?: return@forEach
|
||||||
val eventDate = Date.fromY_m_d(homework.getString("dataO") ?: return@forEach)
|
val eventDate = Date.fromY_m_d(homework.getString("dataO") ?: return@forEach)
|
||||||
|
val addedDate = Date.fromY_m_d(homework.getString("dataZ") ?: return@forEach)
|
||||||
val subjectName = homework.getString("przed") ?: return@forEach
|
val subjectName = homework.getString("przed") ?: return@forEach
|
||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
||||||
val teacherName = homework.getString("usr") ?: return@forEach
|
val teacherName = homework.getString("usr") ?: return@forEach
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate)
|
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
|
||||||
val topic = homework.getString("tytul") ?: ""
|
val topic = homework.getString("tytul")?.trim() ?: ""
|
||||||
|
|
||||||
val seen = when (profile?.empty) {
|
val seen = when (profile?.empty) {
|
||||||
true -> true
|
true -> true
|
||||||
@ -65,17 +68,17 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
|
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
eventDate,
|
date = eventDate,
|
||||||
startTime,
|
time = startTime,
|
||||||
topic,
|
topic = topic,
|
||||||
-1,
|
color = null,
|
||||||
Event.TYPE_HOMEWORK,
|
type = Event.TYPE_HOMEWORK,
|
||||||
false,
|
teacherId = teacherId,
|
||||||
teacherId,
|
subjectId = subjectId,
|
||||||
subjectId,
|
teamId = data.teamClass?.id ?: -1,
|
||||||
data.teamClass?.id ?: -1
|
addedDate = addedDate.inMillis
|
||||||
)
|
)
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
@ -84,15 +87,14 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_HOMEWORK,
|
Metadata.TYPE_HOMEWORK,
|
||||||
eventObject.id,
|
eventObject.id,
|
||||||
seen,
|
seen,
|
||||||
seen,
|
seen
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_HOMEWORK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,27 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_NOTICES
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_NOTICES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_NOTICES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_NOTICES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEGATIVE
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEUTRAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_POSITIVE
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebNotices(override val data: DataIdziennik,
|
class IdziennikWebNotices(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebNotices"
|
private const val TAG = "IdziennikWebNotices"
|
||||||
}
|
}
|
||||||
@ -51,25 +56,29 @@ class IdziennikWebNotices(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val noticeObject = Notice(
|
val noticeObject = Notice(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
noticeId,
|
id = noticeId,
|
||||||
jNotice.get("Tresc").asString,
|
type = nType,
|
||||||
jNotice.get("Semestr").asInt,
|
semester = jNotice.get("Semestr").asInt,
|
||||||
nType,
|
text = jNotice.getString("Tresc") ?: "",
|
||||||
rTeacher.id)
|
category = null,
|
||||||
|
points = null,
|
||||||
|
teacherId = rTeacher.id,
|
||||||
|
addedDate = addedDate.inMillis
|
||||||
|
)
|
||||||
|
|
||||||
data.noticeList.add(noticeObject)
|
data.noticeList.add(noticeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_NOTICE,
|
Metadata.TYPE_NOTICE,
|
||||||
noticeObject.id,
|
noticeObject.id,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false,
|
||||||
profile?.empty ?: false,
|
profile?.empty ?: false
|
||||||
addedDate.inMillis
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_NOTICES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_NOTICES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_NOTICES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,20 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_SEMESTER1_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_YEAR_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
import pl.szczodrzynski.edziennik.getJsonArray
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue
|
|
||||||
|
|
||||||
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebProposedGrades"
|
private const val TAG = "IdziennikWebProposedGrades"
|
||||||
}
|
}
|
||||||
@ -37,35 +39,64 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
.withApiResponse(result))
|
.withApiResponse(result))
|
||||||
return@webApiGet
|
return@webApiGet
|
||||||
}
|
}
|
||||||
|
val manager = data.app.gradesManager
|
||||||
|
|
||||||
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { subject ->
|
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { subject ->
|
||||||
val subjectName = subject.getString("Przedmiot") ?: return@forEach
|
val subjectName = subject.getString("Przedmiot") ?: return@forEach
|
||||||
val subjectObject = data.getSubject(subjectName, null, subjectName)
|
val subjectObject = data.getSubject(subjectName, null, subjectName)
|
||||||
|
|
||||||
val semester1Proposed = subject.getString("OcenaSem1") ?: ""
|
val semester1Proposed = subject.getString("OcenaSem1") ?: ""
|
||||||
val semester1Value = getWordGradeValue(semester1Proposed)
|
val semester1Value = manager.getGradeValue(semester1Proposed)
|
||||||
val semester1Id = subjectObject.id * (-100) - 1
|
val semester1Id = subjectObject.id * (-100) - 1
|
||||||
|
val semester1Type =
|
||||||
|
if (semester1Value == 0f) TYPE_DESCRIPTIVE
|
||||||
|
else TYPE_SEMESTER1_PROPOSED
|
||||||
|
val semester1Name = when {
|
||||||
|
semester1Value == 0f -> " "
|
||||||
|
semester1Value % 1.0f == 0f -> semester1Value.toInt().toString()
|
||||||
|
else -> semester1Value.toString()
|
||||||
|
}
|
||||||
|
val semester1Color =
|
||||||
|
if (semester1Value == 0f) 0xff536dfe.toInt()
|
||||||
|
else -1
|
||||||
|
|
||||||
val semester2Proposed = subject.getString("OcenaSem2") ?: ""
|
val semester2Proposed = subject.getString("OcenaSem2") ?: ""
|
||||||
val semester2Value = getWordGradeValue(semester2Proposed)
|
val semester2Value = manager.getGradeValue(semester2Proposed)
|
||||||
val semester2Id = subjectObject.id * (-100) - 2
|
val semester2Id = subjectObject.id * (-100) - 2
|
||||||
|
val semester2Type =
|
||||||
|
if (semester2Value == 0f) TYPE_DESCRIPTIVE
|
||||||
|
else TYPE_YEAR_PROPOSED
|
||||||
|
val semester2Name = when {
|
||||||
|
semester2Value == 0f -> " "
|
||||||
|
semester2Value % 1.0f == 0f -> semester2Value.toInt().toString()
|
||||||
|
else -> semester2Value.toString()
|
||||||
|
}
|
||||||
|
val semester2Color =
|
||||||
|
if (semester2Value == 0f) 0xffff4081.toInt()
|
||||||
|
else -1
|
||||||
|
|
||||||
if (semester1Proposed != "") {
|
if (semester1Proposed != "") {
|
||||||
|
val addedDate = if (data.profile.empty)
|
||||||
|
data.profile.dateSemester1Start.inMillis
|
||||||
|
else
|
||||||
|
System.currentTimeMillis()
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
semester1Id,
|
id = semester1Id,
|
||||||
"",
|
name = semester1Name,
|
||||||
-1,
|
type = semester1Type,
|
||||||
"",
|
value = semester1Value,
|
||||||
semester1Value.toString(),
|
weight = 0f,
|
||||||
semester1Value.toFloat(),
|
color = semester1Color,
|
||||||
0f,
|
category = if (semester1Value == 0f) "Ocena opisowa semestralna" else null,
|
||||||
1,
|
description = if (semester1Value == 0f) semester1Proposed else null,
|
||||||
-1,
|
comment = null,
|
||||||
subjectObject.id
|
semester = 1,
|
||||||
).apply {
|
teacherId = -1,
|
||||||
type = TYPE_SEMESTER1_PROPOSED
|
subjectId = subjectObject.id,
|
||||||
}
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -73,27 +104,32 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
gradeObject.id,
|
gradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (semester2Proposed != "") {
|
if (semester2Proposed != "") {
|
||||||
|
val addedDate = if (data.profile.empty)
|
||||||
|
data.profile.dateSemester2Start.inMillis
|
||||||
|
else
|
||||||
|
System.currentTimeMillis()
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
semester2Id,
|
id = semester2Id,
|
||||||
"",
|
name = semester2Name,
|
||||||
-1,
|
type = semester2Type,
|
||||||
"",
|
value = semester2Value,
|
||||||
semester2Value.toString(),
|
weight = 0f,
|
||||||
semester2Value.toFloat(),
|
color = semester2Color,
|
||||||
0f,
|
category = if (semester2Value == 0f) "Ocena opisowa końcoworoczna" else null,
|
||||||
2,
|
description = if (semester2Value == 0f) semester2Proposed else null,
|
||||||
-1,
|
comment = null,
|
||||||
subjectObject.id
|
semester = 2,
|
||||||
).apply {
|
teacherId = -1,
|
||||||
type = TYPE_YEAR_PROPOSED
|
subjectId = subjectObject.id,
|
||||||
}
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -101,8 +137,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_GRADE,
|
Metadata.TYPE_GRADE,
|
||||||
gradeObject.id,
|
gradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +146,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
||||||
})
|
})
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,12 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class IdziennikWebSendMessage(
|
class IdziennikWebSendMessage(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik,
|
val recipients: List<Teacher>,
|
||||||
val recipients: List<Teacher>,
|
val subject: String,
|
||||||
val subject: String,
|
val text: String,
|
||||||
val text: String,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : IdziennikWeb(data, null) {
|
||||||
) : IdziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebSendMessage"
|
private const val TAG = "IdziennikWebSendMessage"
|
||||||
}
|
}
|
||||||
@ -57,10 +56,10 @@ class IdziennikWebSendMessage(
|
|||||||
return@webApiGet
|
return@webApiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
IdziennikApiMessagesSent(data) {
|
IdziennikApiMessagesSent(data, null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
EventBus.getDefault().postSticky(event)
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_HOME
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
|
||||||
|
class IdziennikWebSwitchRegister(override val data: DataIdziennik,
|
||||||
|
val registerId: Int,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "IdziennikWebSwitchRegister"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val hiddenFields = data.loginStore.getLoginData("hiddenFields", JsonObject())
|
||||||
|
// TODO error checking
|
||||||
|
|
||||||
|
webGet(TAG, IDZIENNIK_WEB_HOME, mapOf(
|
||||||
|
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
||||||
|
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
||||||
|
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
||||||
|
"ctl00\$dxComboUczniowie" to registerId
|
||||||
|
)) { text ->
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,17 +13,19 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
class IdziennikWebTimetable(override val data: DataIdziennik,
|
class IdziennikWebTimetable(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebTimetable"
|
private const val TAG = "IdziennikWebTimetable"
|
||||||
}
|
}
|
||||||
@ -163,8 +165,7 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
|
|||||||
Metadata.TYPE_LESSON_CHANGE,
|
Metadata.TYPE_LESSON_CHANGE,
|
||||||
lessonObject.id,
|
lessonObject.id,
|
||||||
seen,
|
seen,
|
||||||
seen,
|
seen
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +188,7 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_TIMETABLE)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class IdziennikFirstLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
private const val TAG = "IdziennikFirstLogin"
|
private const val TAG = "IdziennikFirstLogin"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val web = IdziennikWeb(data)
|
private val web = IdziennikWeb(data, null)
|
||||||
private val profileList = mutableListOf<Profile>()
|
private val profileList = mutableListOf<Profile>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -89,7 +89,7 @@ class IdziennikFirstLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
profileList.add(profile)
|
profileList.add(profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore))
|
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,14 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login
|
|||||||
import im.wangchao.mhttp.Request
|
import im.wangchao.mhttp.Request
|
||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import okhttp3.Cookie
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.HOUR
|
|
||||||
import pl.szczodrzynski.edziennik.MINUTE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.getUnixDate
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -24,22 +23,12 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
|
|
||||||
init { run {
|
init { run {
|
||||||
if (data.isWebLoginValid()) {
|
if (data.isWebLoginValid()) {
|
||||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
data.app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", data.webSessionId)
|
||||||
Cookie.Builder()
|
data.app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", data.webAuth)
|
||||||
.name("ASP.NET_SessionId_iDziennik")
|
|
||||||
.value(data.webSessionId!!)
|
|
||||||
.domain("iuczniowie.progman.pl")
|
|
||||||
.secure().httpOnly().build(),
|
|
||||||
Cookie.Builder()
|
|
||||||
.name(".ASPXAUTH")
|
|
||||||
.value(data.webAuth!!)
|
|
||||||
.domain("iuczniowie.progman.pl")
|
|
||||||
.secure().httpOnly().build()
|
|
||||||
))
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.app.cookieJar.clearForDomain("iuczniowie.progman.pl")
|
data.app.cookieJar.clear("iuczniowie.progman.pl")
|
||||||
if (data.webSchoolName != null && data.webUsername != null && data.webPassword != null) {
|
if (data.webSchoolName != null && data.webUsername != null && data.webPassword != null) {
|
||||||
loginWithCredentials()
|
loginWithCredentials()
|
||||||
}
|
}
|
||||||
@ -62,13 +51,54 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
|
|
||||||
// login succeeded: there is a start page
|
// login succeeded: there is a start page
|
||||||
if (text.contains("czyWyswietlicDostepMobilny")) {
|
if (text.contains("czyWyswietlicDostepMobilny")) {
|
||||||
val cookies = data.app.cookieJar.getForDomain("iuczniowie.progman.pl")
|
val cookies = data.app.cookieJar.getAll("iuczniowie.progman.pl")
|
||||||
run {
|
run {
|
||||||
data.webSessionId = cookies.singleOrNull { it.name() == "ASP.NET_SessionId_iDziennik" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
|
data.webSessionId = cookies["ASP.NET_SessionId_iDziennik"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
|
||||||
data.webAuth = cookies.singleOrNull { it.name() == ".ASPXAUTH" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
|
data.webAuth = cookies[".ASPXAUTH"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
|
||||||
data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
data.apiBearer = cookies["Bearer"]?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
||||||
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
||||||
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
||||||
|
|
||||||
|
val hiddenFields = JsonObject()
|
||||||
|
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
||||||
|
hiddenFields[it[1]] = it[2]
|
||||||
|
}
|
||||||
|
data.loginStore.putLoginData("hiddenFields", hiddenFields)
|
||||||
|
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
|
||||||
|
// for profiles created after archiving
|
||||||
|
data.schoolYearId = Regexes.IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR.find(text)?.let {
|
||||||
|
it[1].toIntOrNull()
|
||||||
|
} ?: data.schoolYearId
|
||||||
|
data.profile?.studentClassName = Regexes.IDZIENNIK_LOGIN_FIRST_STUDENT.findAll(text)
|
||||||
|
.firstOrNull { it[1].toIntOrNull() == data.registerId }
|
||||||
|
?.let { "${it[5]} ${it[6]}" } ?: data.profile?.studentClassName
|
||||||
|
|
||||||
|
data.profile?.let { profile ->
|
||||||
|
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
|
||||||
|
val number = it[1].toIntOrNull() ?: return@also
|
||||||
|
val luckyNumberObject = LuckyNumber(
|
||||||
|
profileId = data.profileId,
|
||||||
|
date = Date.getToday(),
|
||||||
|
number = number
|
||||||
|
)
|
||||||
|
|
||||||
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profile.id,
|
||||||
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
|
luckyNumberObject.date.value.toLong(),
|
||||||
|
true,
|
||||||
|
profile.empty
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return@run null
|
return@run null
|
||||||
}?.let { errorCode ->
|
}?.let { errorCode ->
|
||||||
data.error(ApiError(TAG, errorCode)
|
data.error(ApiError(TAG, errorCode)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.librus
|
package pl.szczodrzynski.edziennik.data.api.edziennik.librus
|
||||||
|
|
||||||
import okhttp3.Cookie
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_API
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_API
|
||||||
@ -31,23 +30,11 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
loginMethods += LOGIN_METHOD_LIBRUS_API
|
loginMethods += LOGIN_METHOD_LIBRUS_API
|
||||||
if (isSynergiaLoginValid()) {
|
if (isSynergiaLoginValid()) {
|
||||||
loginMethods += LOGIN_METHOD_LIBRUS_SYNERGIA
|
loginMethods += LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||||
app.cookieJar.saveFromResponse(null, listOf(
|
app.cookieJar.set("synergia.librus.pl", "DZIENNIKSID", synergiaSessionId)
|
||||||
Cookie.Builder()
|
|
||||||
.name("DZIENNIKSID")
|
|
||||||
.value(synergiaSessionId!!)
|
|
||||||
.domain("synergia.librus.pl")
|
|
||||||
.secure().httpOnly().build()
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
if (isMessagesLoginValid()) {
|
if (isMessagesLoginValid()) {
|
||||||
loginMethods += LOGIN_METHOD_LIBRUS_MESSAGES
|
loginMethods += LOGIN_METHOD_LIBRUS_MESSAGES
|
||||||
app.cookieJar.saveFromResponse(null, listOf(
|
app.cookieJar.set("wiadomosci.librus.pl", "DZIENNIKSID", messagesSessionId)
|
||||||
Cookie.Builder()
|
|
||||||
.name("DZIENNIKSID")
|
|
||||||
.value(messagesSessionId!!)
|
|
||||||
.domain("wiadomosci.librus.pl")
|
|
||||||
.secure().httpOnly().build()
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +120,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
private var mApiLogin: String? = null
|
private var mApiLogin: String? = null
|
||||||
var apiLogin: String?
|
var apiLogin: String?
|
||||||
get() { mApiLogin = mApiLogin ?: profile?.getStudentData("accountLogin", null); return mApiLogin }
|
get() { mApiLogin = mApiLogin ?: profile?.getStudentData("accountLogin", null); return mApiLogin }
|
||||||
set(value) { profile?.putStudentData("accountLogin", value) ?: return; mApiLogin = value }
|
set(value) { profile?.putStudentData("accountLogin", value); mApiLogin = value }
|
||||||
/**
|
/**
|
||||||
* A Synergia password.
|
* A Synergia password.
|
||||||
* Used: for login (API Login Method) in Synergia mode.
|
* Used: for login (API Login Method) in Synergia mode.
|
||||||
@ -142,7 +129,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
private var mApiPassword: String? = null
|
private var mApiPassword: String? = null
|
||||||
var apiPassword: String?
|
var apiPassword: String?
|
||||||
get() { mApiPassword = mApiPassword ?: profile?.getStudentData("accountPassword", null); return mApiPassword }
|
get() { mApiPassword = mApiPassword ?: profile?.getStudentData("accountPassword", null); return mApiPassword }
|
||||||
set(value) { profile?.putStudentData("accountPassword", value) ?: return; mApiPassword = value }
|
set(value) { profile?.putStudentData("accountPassword", value); mApiPassword = value }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JST login Code.
|
* A JST login Code.
|
||||||
@ -151,8 +138,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
private var mApiCode: String? = null
|
private var mApiCode: String? = null
|
||||||
var apiCode: String?
|
var apiCode: String?
|
||||||
get() { mApiCode = mApiCode ?: loginStore.getLoginData("accountCode", null); return mApiCode }
|
get() { mApiCode = mApiCode ?: loginStore.getLoginData("accountCode", null); return mApiCode }
|
||||||
set(value) {
|
set(value) { profile?.putStudentData("accountCode", value); mApiCode = value }
|
||||||
loginStore.putLoginData("accountCode", value); mApiCode = value }
|
|
||||||
/**
|
/**
|
||||||
* A JST login PIN.
|
* A JST login PIN.
|
||||||
* Used only during first login in JST mode.
|
* Used only during first login in JST mode.
|
||||||
@ -160,8 +146,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
private var mApiPin: String? = null
|
private var mApiPin: String? = null
|
||||||
var apiPin: String?
|
var apiPin: String?
|
||||||
get() { mApiPin = mApiPin ?: loginStore.getLoginData("accountPin", null); return mApiPin }
|
get() { mApiPin = mApiPin ?: loginStore.getLoginData("accountPin", null); return mApiPin }
|
||||||
set(value) {
|
set(value) { profile?.putStudentData("accountPin", value); mApiPin = value }
|
||||||
loginStore.putLoginData("accountPin", value); mApiPin = value }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Synergia API access token.
|
* A Synergia API access token.
|
||||||
@ -191,6 +176,16 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
get() { mApiTokenExpiryTime = mApiTokenExpiryTime ?: profile?.getStudentData("accountTokenTime", 0L); return mApiTokenExpiryTime ?: 0L }
|
get() { mApiTokenExpiryTime = mApiTokenExpiryTime ?: profile?.getStudentData("accountTokenTime", 0L); return mApiTokenExpiryTime ?: 0L }
|
||||||
set(value) { mApiTokenExpiryTime = value; profile?.putStudentData("accountTokenTime", value) ?: return; }
|
set(value) { mApiTokenExpiryTime = value; profile?.putStudentData("accountTokenTime", value) ?: return; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A push device ID, generated by Librus when registering
|
||||||
|
* a FCM token. I don't really know if this has any use,
|
||||||
|
* but it may be worthy to save that ID.
|
||||||
|
*/
|
||||||
|
private var mPushDeviceId: Int? = null
|
||||||
|
var pushDeviceId: Int
|
||||||
|
get() { mPushDeviceId = mPushDeviceId ?: profile?.getStudentData("pushDeviceId", 0); return mPushDeviceId ?: 0 }
|
||||||
|
set(value) { mPushDeviceId = value; profile?.putStudentData("pushDeviceId", value) ?: return; }
|
||||||
|
|
||||||
/* _____ _
|
/* _____ _
|
||||||
/ ____| (_)
|
/ ____| (_)
|
||||||
| (___ _ _ _ __ ___ _ __ __ _ _ __ _
|
| (___ _ _ _ __ ___ _ __ __ _ _ __ _
|
||||||
@ -280,4 +275,10 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
var timetableNotPublic: Boolean
|
var timetableNotPublic: Boolean
|
||||||
get() { mTimetableNotPublic = mTimetableNotPublic ?: profile?.getStudentData("timetableNotPublic", false); return mTimetableNotPublic ?: false }
|
get() { mTimetableNotPublic = mTimetableNotPublic ?: profile?.getStudentData("timetableNotPublic", false); return mTimetableNotPublic ?: false }
|
||||||
set(value) { profile?.putStudentData("timetableNotPublic", value) ?: return; mTimetableNotPublic = value }
|
set(value) { profile?.putStudentData("timetableNotPublic", value) ?: return; mTimetableNotPublic = value }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to false when Recaptcha helper doesn't provide a working token.
|
||||||
|
* When it's set to false uses Synergia for messages.
|
||||||
|
*/
|
||||||
|
var messagesLoginSuccessful: Boolean = true
|
||||||
}
|
}
|
||||||
|
@ -13,18 +13,19 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.Librus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetMessage
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetMessage
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetRecipientList
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesGetRecipientList
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesSendMessage
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.LibrusMessagesSendMessage
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaMarkAllAnnouncementsAsRead
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -45,9 +46,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -58,9 +57,9 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId)
|
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,9 +89,8 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
override fun getMessage(message: MessageFull) {
|
override fun getMessage(message: MessageFull) {
|
||||||
login(LOGIN_METHOD_LIBRUS_MESSAGES) {
|
login(LOGIN_METHOD_LIBRUS_MESSAGES) {
|
||||||
LibrusMessagesGetMessage(data, message) {
|
if (data.messagesLoginSuccessful) LibrusMessagesGetMessage(data, message) { completed() }
|
||||||
completed()
|
else LibrusSynergiaGetMessage(data, message) { completed() }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +118,22 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) {
|
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||||
login(LOGIN_METHOD_LIBRUS_MESSAGES) {
|
when (owner) {
|
||||||
LibrusMessagesGetAttachment(data, message, attachmentId, attachmentName) {
|
is Message -> {
|
||||||
completed()
|
login(LOGIN_METHOD_LIBRUS_SYNERGIA) {
|
||||||
|
if (data.messagesLoginSuccessful) LibrusMessagesGetAttachment(data, owner, attachmentId, attachmentName) { completed() }
|
||||||
|
LibrusSynergiaGetAttachment(data, owner, attachmentId, attachmentName) { completed() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
is EventFull -> {
|
||||||
|
login(LOGIN_METHOD_LIBRUS_SYNERGIA) {
|
||||||
|
LibrusSynergiaHomeworkGetAttachment(data, owner, attachmentId, attachmentName) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +145,14 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getEvent(eventFull: EventFull) {
|
||||||
|
login(LOGIN_METHOD_LIBRUS_SYNERGIA) {
|
||||||
|
LibrusSynergiaGetHomework(data, eventFull) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun firstLogin() { LibrusFirstLogin(data) { completed() } }
|
override fun firstLogin() { LibrusFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
d(TAG, "Cancelled")
|
d(TAG, "Cancelled")
|
||||||
@ -182,6 +199,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE,
|
ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING,
|
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING,
|
||||||
|
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED,
|
ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED -> {
|
ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED -> {
|
||||||
login()
|
login()
|
||||||
@ -200,7 +218,6 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID -> {
|
ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID -> {
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
// TODO PORTAL CAPTCHA
|
|
||||||
ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC -> {
|
ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC -> {
|
||||||
data.timetableNotPublic = true
|
data.timetableNotPublic = true
|
||||||
data()
|
data()
|
||||||
@ -209,6 +226,11 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
ERROR_LIBRUS_API_NOTES_NOT_ACTIVE -> {
|
ERROR_LIBRUS_API_NOTES_NOT_ACTIVE -> {
|
||||||
data()
|
data()
|
||||||
}
|
}
|
||||||
|
ERROR_LIBRUS_API_DEVICE_REGISTERED -> {
|
||||||
|
data.app.config.sync.tokenLibrusList =
|
||||||
|
data.app.config.sync.tokenLibrusList + data.profileId
|
||||||
|
data()
|
||||||
|
}
|
||||||
else -> callback.onError(apiError)
|
else -> callback.onError(apiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,11 @@ const val ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS = 1130
|
|||||||
const val ENDPOINT_LIBRUS_SYNERGIA_INFO = 2010
|
const val ENDPOINT_LIBRUS_SYNERGIA_INFO = 2010
|
||||||
const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 2020
|
const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 2020
|
||||||
const val ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK = 2030
|
const val ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK = 2030
|
||||||
|
const val ENDPOINT_LIBRUS_SYNERGIA_MESSAGES_RECEIVED = 2040
|
||||||
|
const val ENDPOINT_LIBRUS_SYNERGIA_MESSAGES_SENT = 2050
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 3010
|
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 3010
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_SENT = 3020
|
const val ENDPOINT_LIBRUS_MESSAGES_SENT = 3020
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 3030
|
const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 3030
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVERS = 3040
|
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_GET = 3040
|
|
||||||
|
|
||||||
val LibrusFeatures = listOf(
|
val LibrusFeatures = listOf(
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ val LibrusFeatures = listOf(
|
|||||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_PUSH_CONFIG, listOf(
|
Feature(LOGIN_TYPE_LIBRUS, FEATURE_PUSH_CONFIG, listOf(
|
||||||
ENDPOINT_LIBRUS_API_PUSH_CONFIG to LOGIN_METHOD_LIBRUS_API
|
ENDPOINT_LIBRUS_API_PUSH_CONFIG to LOGIN_METHOD_LIBRUS_API
|
||||||
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
||||||
!data.app.config.sync.tokenLibrusList.contains(data.profileId)
|
(data as DataLibrus).isPremium && !data.app.config.sync.tokenLibrusList.contains(data.profileId)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -118,11 +118,11 @@ val LibrusFeatures = listOf(
|
|||||||
* Homework - using API.
|
* Homework - using API.
|
||||||
* Sync only if account has premium access.
|
* Sync only if account has premium access.
|
||||||
*/
|
*/
|
||||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
/*Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||||
ENDPOINT_LIBRUS_API_HOMEWORK to LOGIN_METHOD_LIBRUS_API
|
ENDPOINT_LIBRUS_API_HOMEWORK to LOGIN_METHOD_LIBRUS_API
|
||||||
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
||||||
(data as DataLibrus).isPremium
|
(data as DataLibrus).isPremium
|
||||||
},
|
},*/
|
||||||
/**
|
/**
|
||||||
* Behaviour - using API.
|
* Behaviour - using API.
|
||||||
*/
|
*/
|
||||||
@ -229,9 +229,9 @@ val LibrusFeatures = listOf(
|
|||||||
*/
|
*/
|
||||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||||
ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK to LOGIN_METHOD_LIBRUS_SYNERGIA
|
ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)).withShouldSync { data ->
|
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA))/*.withShouldSync { data ->
|
||||||
!(data as DataLibrus).isPremium
|
!(data as DataLibrus).isPremium
|
||||||
},
|
}*/,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Messages inbox - using messages website.
|
* Messages inbox - using messages website.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user