Compare commits
369 Commits
Author | SHA1 | Date | |
---|---|---|---|
2d6d823a87 | |||
02a9724587 | |||
c17237015e | |||
2681794676 | |||
42e59ac0db | |||
cac98ee3d4 | |||
aeecc48639 | |||
db444d89f0 | |||
29971777a7 | |||
88cd18b8c6 | |||
30a77f1a99 | |||
6de7ee9cee | |||
d44b85073a | |||
514fbafd00 | |||
c35222cdfd | |||
37a94595c0 | |||
58d9dec33c | |||
095403cc76 | |||
7f3a607246 | |||
ffee78d4f7 | |||
f2a20c3aae | |||
1e7dbba995 | |||
0b8f3fe94b | |||
0e8b0673ca | |||
8450f6953e | |||
ddefda08f1 | |||
c5b173b40a | |||
f10bc42c7b | |||
6371d71b7a | |||
09f0c986e0 | |||
10043cc62c | |||
f795412551 | |||
6a7020a516 | |||
137ea65e0f | |||
50ef7f8617 | |||
e1dbc2f050 | |||
77e1acbb1e | |||
6e19f37d79 | |||
0823e72328 | |||
fadf1d7754 | |||
1071a0848a | |||
cefb0deba8 | |||
53c813f014 | |||
90a151c129 | |||
9fd9721ae7 | |||
ceca75ef4b | |||
21c00bbe53 | |||
db00566ebf | |||
07ab1b984f | |||
8177d4aa2d | |||
beff1b6460 | |||
31b569b02e | |||
8bf77817d2 | |||
87b7bd9b30 | |||
27b61adf1d | |||
8d7dc511ea | |||
a0244841ad | |||
12c0c6f2ec | |||
aaa3b8626e | |||
48c9e2dfe3 | |||
81d4801d27 | |||
5f8016061d | |||
5007587192 | |||
dfd1083e41 | |||
a322986df5 | |||
678baf46e5 | |||
4077fe448d | |||
f085e17ef7 | |||
7fd2cad46b | |||
93dc2ac9ab | |||
ac53e267fc | |||
86eb1a0f42 | |||
710d82da27 | |||
0123f50810 | |||
6d3eb65445 | |||
a9a0630226 | |||
ec7577f999 | |||
05c7c0012c | |||
d65c6db954 | |||
771dc437e6 | |||
3d5d3847cc | |||
726c22b70a | |||
18cc60a80b | |||
fedde9f739 | |||
9fde97bef0 | |||
742bd03e9e | |||
62ffc652ab | |||
bfd2e9883a | |||
00e077d01f | |||
c21d89cf60 | |||
f52cc1b197 | |||
c90ad97f55 | |||
845e09d875 | |||
158b69a8d3 | |||
9535f53563 | |||
eeb3fc4621 | |||
41693a9fc8 | |||
d3599b8c89 | |||
ffd81f8b82 | |||
2c34924052 | |||
26ad6373e6 | |||
cac8f94407 | |||
6628b97faf | |||
8424414317 | |||
d8bb927703 | |||
c8e8c172a2 | |||
0d4dee765a | |||
fd407b2b03 | |||
40ed5a221f | |||
5150467372 | |||
63c5720f63 | |||
6c93cd4217 | |||
649d4f619a | |||
ba10d10a10 | |||
1450d63fcb | |||
2ec06bc39a | |||
6f12227c2e | |||
3a91f87ccd | |||
52a53334ca | |||
3ab9602865 | |||
dc19043f73 | |||
cf25507850 | |||
044cedff99 | |||
4de066bf5f | |||
8d174bda01 | |||
e2fd714070 | |||
8097e8d06d | |||
93ccdbdeb7 | |||
7ded400a30 | |||
2ff784066e | |||
6c96875c83 | |||
9f3aaf6e86 | |||
55369eaa8b | |||
c983c16907 | |||
c7362bce12 | |||
7935d0f097 | |||
4b64277948 | |||
ef0996c80e | |||
132729bbd9 | |||
6d36ab27d1 | |||
11fabb231f | |||
6fd999f88c | |||
7711413b30 | |||
cdc0c9d458 | |||
8e5f750a80 | |||
f4e7e8978c | |||
14952307b3 | |||
96c542d6d2 | |||
77d22b87aa | |||
37c68443bd | |||
9dbb5d70e9 | |||
99afa77a63 | |||
a5d0f4212d | |||
a85f935eb4 | |||
bb44fa066c | |||
54a61c6254 | |||
ac10874bf1 | |||
fa55b4901a | |||
86c41d9191 | |||
0f90430387 | |||
745523c620 | |||
c1ef0e9d11 | |||
8911ce2bc1 | |||
2990fc5479 | |||
48b7adb564 | |||
2e97467c57 | |||
f8ac9e793a | |||
148597e578 | |||
6c50a80b42 | |||
1bf0679e92 | |||
5b5dc5cade | |||
46de915965 | |||
98a89b1ca1 | |||
6d1e18cce2 | |||
8fe0f88be4 | |||
aeed735521 | |||
e314fafaff | |||
2ab0dd7546 | |||
aa06868a4e | |||
9a6d56ec77 | |||
2b104e6463 | |||
afb1863827 | |||
d8228748e4 | |||
b0608c47c4 | |||
dda0d88f19 | |||
a1b5560977 | |||
86f5811bda | |||
3f11e75985 | |||
c39b5442c9 | |||
3b80adf355 | |||
cae41d17b6 | |||
519d75d9d9 | |||
cb953ea8a8 | |||
52968cafad | |||
b7755dae96 | |||
113ecc0ef1 | |||
23bd9b8e05 | |||
decfd2068a | |||
a88cfb8ae3 | |||
50cb0acc7d | |||
27413a9745 | |||
49a093201b | |||
7c925cb88a | |||
8745d7d526 | |||
e02246f97d | |||
e629e03b33 | |||
e2ad3758e0 | |||
f3e2d21b89 | |||
fd62653d79 | |||
ca3e6f7fc9 | |||
d8abac1917 | |||
2807659da3 | |||
7884bf4077 | |||
59f80c049c | |||
f1e58db151 | |||
74b766f18a | |||
7e0f69d95d | |||
fa318d4509 | |||
63b74a9fda | |||
1a543814f4 | |||
50ae767fcd | |||
44263ac95f | |||
a6aca42c8c | |||
83daae46b8 | |||
6611fc5843 | |||
fe82c86c93 | |||
692555732d | |||
d59286bb05 | |||
91cfa7e945 | |||
2d277e80cc | |||
3cdca5eb33 | |||
591abb4bb8 | |||
0b4421c7a7 | |||
325efd8b14 | |||
959168771b | |||
41217190bb | |||
18c306b9ea | |||
c6be1a7954 | |||
e8e9f04050 | |||
3700a71c39 | |||
60f0628f5e | |||
80dcd9aa69 | |||
d60e622626 | |||
91b685576b | |||
2e3e3dcf3c | |||
118f5e1794 | |||
e902352a4b | |||
2f7fcb6dc3 | |||
21ddb9d706 | |||
efa63452e7 | |||
83f84de019 | |||
b9aca981e5 | |||
5913707519 | |||
dd6a2c0979 | |||
9fdee6e0c7 | |||
b31bf5c1ab | |||
cf4906f2f4 | |||
680a5dfea3 | |||
c1062cd7ed | |||
8edc581f0b | |||
ea9d801d08 | |||
8f72e11d0c | |||
452271e8c0 | |||
7b4effe889 | |||
e2bf48d1b6 | |||
c88056ddb9 | |||
96dbb0a057 | |||
288c80ea26 | |||
5a217aca01 | |||
4bed62aa6f | |||
a4d604e146 | |||
ae4405ef78 | |||
71ca51e813 | |||
1bf07d736f | |||
c011f550bb | |||
909899612e | |||
4184fbb2cd | |||
75010c0771 | |||
5562498e84 | |||
c2d0940a80 | |||
baa98f25c5 | |||
26645ee83c | |||
85d74bec1c | |||
fd0fc652a3 | |||
c85dac2e4d | |||
c855f08f9c | |||
a31c68e87a | |||
99021f6b3a | |||
e2b47db3fd | |||
8609956ae7 | |||
e25ca930e0 | |||
47ec1899a1 | |||
1e8fb6a9ae | |||
02eb5b7ee4 | |||
776806caef | |||
755b846b50 | |||
73f3ba17de | |||
07fb1e0e12 | |||
297867cbf3 | |||
db598af28a | |||
ec765c9070 | |||
5eaa754401 | |||
b48b5589f4 | |||
634ef16bc5 | |||
ccf0bdaf05 | |||
4647da7803 | |||
613f271c4e | |||
8b1529f240 | |||
3eb09033bf | |||
12619f6bde | |||
f5ceaa9afe | |||
777ae945e0 | |||
3eae8fb58b | |||
b14ef5cd78 | |||
98bf4f3bdc | |||
2d6cf50ca7 | |||
95baf9fb9c | |||
61b7410bd0 | |||
dd0972b528 | |||
d5c10fbd2b | |||
d17f6297d3 | |||
3ae785a45c | |||
dd254d4bec | |||
e04bd75f1f | |||
929ccb53db | |||
72319a4613 | |||
e389e6c073 | |||
cd6951dcbb | |||
02d60754b6 | |||
6884251646 | |||
582e2059d8 | |||
ea2974bfae | |||
b8ff649c96 | |||
8661ecdafb | |||
fe8cbc061d | |||
b4459e1fd4 | |||
fd6553871f | |||
a4ca44e1ce | |||
e124c429d1 | |||
e9a2dae1e4 | |||
8b0f3490e3 | |||
131606a6cf | |||
cacafa205e | |||
9c620de1e7 | |||
3e98fb967b | |||
8db81478f3 | |||
8f9861bac6 | |||
5b35e3500e | |||
fc4c297bef | |||
e7cb699bcf | |||
5301b4efad | |||
bf595dd09c | |||
cb4b168b2a | |||
b2fcbb8289 | |||
fd31cafd8f | |||
df7044cc64 | |||
0a127ac6ee | |||
6b75715e87 | |||
b9e0d91220 | |||
0d5bb331f3 | |||
0e52fb7386 | |||
339bb9c8f6 | |||
b44fa6b2e4 | |||
9cc98fcf08 | |||
67b794ce2b | |||
31b502bb6c | |||
7686c451e6 | |||
04f3ce4d64 | |||
3a6087e421 |
BIN
.github/readme-banner.png
vendored
Normal file
After Width: | Height: | Size: 60 KiB |
2
.github/utils/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.env
|
||||
__pycache__/
|
55
.github/utils/_get_password.py
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
import base64
|
||||
import secrets
|
||||
from hashlib import sha256
|
||||
from typing import Tuple
|
||||
|
||||
import mysql.connector as mysql
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
|
||||
def get_password(
|
||||
version_name: str,
|
||||
version_code: int,
|
||||
db_host: str,
|
||||
db_user: str,
|
||||
db_pass: str,
|
||||
db_name: str,
|
||||
) -> Tuple[str, bytes]:
|
||||
db = mysql.connect(
|
||||
host=db_host,
|
||||
user=db_user,
|
||||
password=db_pass,
|
||||
database=db_name,
|
||||
auth_plugin="mysql_native_password",
|
||||
)
|
||||
|
||||
password = base64.b64encode(secrets.token_bytes(16)).decode()
|
||||
iv = secrets.token_bytes(16)
|
||||
|
||||
key = f"{version_name}.{password}.{version_code}"
|
||||
key = sha256(key.encode()).digest()
|
||||
data = "ThisIsOurHardWorkPleaseDoNotCopyOrSteal(c)2019.KubaSz"
|
||||
data = sha256(data.encode()).digest()
|
||||
data = data + (chr(16) * 16).encode()
|
||||
|
||||
aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
|
||||
|
||||
app_password = base64.b64encode(aes.encrypt(data)).decode()
|
||||
|
||||
c = db.cursor()
|
||||
c.execute(
|
||||
"INSERT IGNORE INTO _appPasswords (versionCode, appPassword, password, iv) VALUES (%s, %s, %s, %s);",
|
||||
(version_code, app_password, password, iv),
|
||||
)
|
||||
db.commit()
|
||||
|
||||
c = db.cursor()
|
||||
c.execute(
|
||||
"SELECT password, iv FROM _appPasswords WHERE versionCode = %s;",
|
||||
(version_code,),
|
||||
)
|
||||
row = c.fetchone()
|
||||
|
||||
db.close()
|
||||
|
||||
return (row[0], row[1])
|
144
.github/utils/_utils.py
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Tuple
|
||||
|
||||
VERSION_NAME_REGEX = r'versionName: "(.+?)"'
|
||||
VERSION_CODE_REGEX = r"versionCode: ([0-9]+)"
|
||||
VERSION_NAME_FORMAT = 'versionName: "{}"'
|
||||
VERSION_CODE_FORMAT = "versionCode: {}"
|
||||
|
||||
|
||||
def get_project_dir() -> str:
|
||||
project_dir = sys.argv[1]
|
||||
if project_dir[-1:] == "/" or project_dir[-1:] == "\\":
|
||||
project_dir = project_dir[:-1]
|
||||
return project_dir
|
||||
|
||||
|
||||
def read_gradle_version(project_dir: str) -> Tuple[int, str]:
|
||||
GRADLE_PATH = f"{project_dir}/build.gradle"
|
||||
|
||||
with open(GRADLE_PATH, "r") as f:
|
||||
gradle = f.read()
|
||||
|
||||
version_name = re.search(VERSION_NAME_REGEX, gradle).group(1)
|
||||
version_code = int(re.search(VERSION_CODE_REGEX, gradle).group(1))
|
||||
|
||||
return (version_code, version_name)
|
||||
|
||||
|
||||
def write_gradle_version(project_dir: str, version_code: int, version_name: str):
|
||||
GRADLE_PATH = f"{project_dir}/build.gradle"
|
||||
|
||||
with open(GRADLE_PATH, "r") as f:
|
||||
gradle = f.read()
|
||||
|
||||
gradle = re.sub(
|
||||
VERSION_NAME_REGEX, VERSION_NAME_FORMAT.format(version_name), gradle
|
||||
)
|
||||
gradle = re.sub(
|
||||
VERSION_CODE_REGEX, VERSION_CODE_FORMAT.format(version_code), gradle
|
||||
)
|
||||
|
||||
with open(GRADLE_PATH, "w") as f:
|
||||
f.write(gradle)
|
||||
|
||||
|
||||
def build_version_code(version_name: str) -> int:
|
||||
version = version_name.split("+")[0].split("-")
|
||||
version_base = version[0]
|
||||
version_suffix = version[1] if len(version) == 2 else ""
|
||||
|
||||
base_parts = version_base.split(".")
|
||||
major = int(base_parts[0]) or 0
|
||||
minor = int(base_parts[1]) if len(base_parts) > 1 else 0
|
||||
patch = int(base_parts[2]) if len(base_parts) > 2 else 0
|
||||
|
||||
beta = 9
|
||||
rc = 9
|
||||
if "dev" in version_suffix:
|
||||
beta = 0
|
||||
rc = 0
|
||||
elif "beta." in version_suffix:
|
||||
beta = int(version_suffix.split(".")[1])
|
||||
rc = 0
|
||||
elif "rc." in version_suffix:
|
||||
beta = 0
|
||||
rc = int(version_suffix.split(".")[1])
|
||||
|
||||
version_code = beta + rc * 10 + patch * 100 + minor * 10000 + major * 1000000
|
||||
return version_code
|
||||
|
||||
|
||||
def get_changelog(project_dir: str, format: str) -> Tuple[str, str]:
|
||||
with open(
|
||||
f"{project_dir}/app/src/main/assets/pl-changelog.html", "r", encoding="utf-8"
|
||||
) as f:
|
||||
changelog = f.read()
|
||||
|
||||
title = re.search(r"<h3>(.+?)</h3>", changelog).group(1)
|
||||
content = re.search(r"(?s)<ul>(.+)</ul>", changelog).group(1).strip()
|
||||
content = "\n".join(line.strip() for line in content.split("\n"))
|
||||
|
||||
if format != "html":
|
||||
content = content.replace("<li>", "- ")
|
||||
content = content.replace("<br>", "\n")
|
||||
if format == "markdown":
|
||||
content = re.sub(r"<u>(.+?)</u>", "__\\1__", content)
|
||||
content = re.sub(r"<i>(.+?)</i>", "*\\1*", content)
|
||||
content = re.sub(r"<b>(.+?)</b>", "**\\1**", content)
|
||||
content = re.sub(r"</?.+?>", "", content)
|
||||
|
||||
return (title, content)
|
||||
|
||||
|
||||
def get_commit_log(project_dir: str, format: str, max_lines: int = None) -> str:
|
||||
last_tag = (
|
||||
subprocess.check_output("git describe --tags --abbrev=0".split(" "))
|
||||
.decode()
|
||||
.strip()
|
||||
)
|
||||
|
||||
log = subprocess.run(
|
||||
args=f"git log {last_tag}..HEAD --format=%an%x00%at%x00%h%x00%s%x00%D".split(
|
||||
" "
|
||||
),
|
||||
cwd=project_dir,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
log = log.stdout.strip().decode()
|
||||
|
||||
commits = [line.split("\x00") for line in log.split("\n")]
|
||||
if max_lines:
|
||||
commits = commits[:max_lines]
|
||||
|
||||
output = []
|
||||
valid = False
|
||||
|
||||
for commit in commits:
|
||||
if not commit[0]:
|
||||
continue
|
||||
if "origin/" in commit[4]:
|
||||
valid = True
|
||||
if not valid:
|
||||
continue
|
||||
date = datetime.fromtimestamp(float(commit[1]))
|
||||
date = date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
if format == "html":
|
||||
output.append(f"<li>{commit[3]} <i> - {commit[0]}</i></li>")
|
||||
elif format == "markdown":
|
||||
output.append(f"[{date}] {commit[0]}\n {commit[3]}")
|
||||
elif format == "markdown_full":
|
||||
output.append(
|
||||
f"_[{date}] {commit[0]}_\n` `__`{commit[2]}`__ **{commit[3]}**"
|
||||
)
|
||||
elif format == "plain":
|
||||
output.append(f"- {commit[3]}")
|
||||
|
||||
if format == "markdown":
|
||||
output.insert(0, "```")
|
||||
output.append("```")
|
||||
|
||||
return "\n".join(output)
|
48
.github/utils/bump_nightly.py
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from _utils import (
|
||||
get_commit_log,
|
||||
get_project_dir,
|
||||
read_gradle_version,
|
||||
write_gradle_version,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: bump_nightly.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
version_name = version_name.split("+")[0]
|
||||
|
||||
date = datetime.now(tz=ZoneInfo("Europe/Warsaw"))
|
||||
if date.hour > 6:
|
||||
version_name += "+daily." + date.strftime("%Y%m%d-%H%M")
|
||||
else:
|
||||
date -= timedelta(days=1)
|
||||
version_name += "+nightly." + date.strftime("%Y%m%d")
|
||||
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
write_gradle_version(project_dir, version_code, version_name)
|
||||
|
||||
commit_log = get_commit_log(project_dir, format="html", max_lines=10)
|
||||
|
||||
with open(
|
||||
f"{project_dir}/app/src/main/assets/pl-changelog.html", "r", encoding="utf-8"
|
||||
) as f:
|
||||
changelog = f.read()
|
||||
|
||||
changelog = re.sub(r"<h3>(.+?)</h3>", f"<h3>{version_name}</h3>", changelog)
|
||||
changelog = re.sub(r"(?s)<ul>(.+)</ul>", f"<ul>\n{commit_log}\n</ul>", changelog)
|
||||
|
||||
with open(
|
||||
f"{project_dir}/app/src/main/assets/pl-changelog.html", "w", encoding="utf-8"
|
||||
) as f:
|
||||
f.write(changelog)
|
41
.github/utils/bump_version.py
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from _get_password import get_password
|
||||
from _utils import build_version_code, write_gradle_version
|
||||
from sign import sign
|
||||
|
||||
if __name__ == "__main__":
|
||||
version_name = input("Enter version name: ")
|
||||
version_code = build_version_code(version_name)
|
||||
|
||||
print(f"Bumping version to {version_name} ({version_code})")
|
||||
|
||||
project_dir = "../.."
|
||||
|
||||
load_dotenv()
|
||||
DB_HOST = os.getenv("DB_HOST")
|
||||
DB_USER = os.getenv("DB_USER")
|
||||
DB_PASS = os.getenv("DB_PASS")
|
||||
DB_NAME = os.getenv("DB_NAME")
|
||||
|
||||
write_gradle_version(project_dir, version_code, version_name)
|
||||
(password, iv) = get_password(
|
||||
version_name, version_code, DB_HOST, DB_USER, DB_PASS, DB_NAME
|
||||
)
|
||||
|
||||
sign(project_dir, version_name, version_code, password, iv, commit=False)
|
||||
|
||||
print("Writing mock passwords")
|
||||
os.chdir(project_dir)
|
||||
os.system(
|
||||
"sed -i -E 's/\/\*([0-9a-f]{2} ?){16}\*\//\/*secret password - removed for source code publication*\//g' app/src/main/cpp/szkolny-signing.cpp"
|
||||
)
|
||||
os.system(
|
||||
"sed -i -E 's/\\t0x.., 0x(.)., 0x.(.), 0x.(.), 0x.., 0x.., 0x.., 0x.(.), 0x.., 0x.(.), 0x(.)., 0x(.)., 0x.., 0x.., 0x.., 0x.(.)/\\t0x\\3\\6, 0x\\7\\4, 0x\\1\\8, 0x\\2\\5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /g' app/src/main/cpp/szkolny-signing.cpp"
|
||||
)
|
||||
os.system(
|
||||
"sed -i -E 's/param1\..(.).(.).(.).(.)..(.)..(.)..(.)..(.).../param1.MTIzNDU2Nzg5MD\\5\\2\\7\\6\\1\\3\\4\8==/g' app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt"
|
||||
)
|
||||
input("Press any key to finish")
|
23
.github/utils/check_nightly.py
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
if __name__ == "__main__":
|
||||
repo = os.getenv("GITHUB_REPOSITORY")
|
||||
sha = os.getenv("GITHUB_SHA")
|
||||
|
||||
if not repo or not sha:
|
||||
print("Missing GitHub environment variables.")
|
||||
exit(-1)
|
||||
|
||||
with requests.get(
|
||||
f"https://api.github.com/repos/{repo}/actions/runs?per_page=5&status=success"
|
||||
) as r:
|
||||
data = json.loads(r.text)
|
||||
runs = [run for run in data["workflow_runs"] if run["head_sha"] == sha]
|
||||
if runs:
|
||||
print("hasNewChanges=false")
|
||||
exit(0)
|
||||
|
||||
print("hasNewChanges=true")
|
71
.github/utils/extract_changelogs.py
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from _utils import get_changelog, get_commit_log, get_project_dir, read_gradle_version
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: extract_changelogs.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
dir = f"{project_dir}/app/release/whatsnew-{version_name}/"
|
||||
os.makedirs(dir, exist_ok=True)
|
||||
|
||||
print("changelogDir=" + dir)
|
||||
|
||||
(title, changelog) = get_changelog(project_dir, format="plain")
|
||||
|
||||
# plain text changelog - Firebase App Distribution
|
||||
with open(dir + "whatsnew_titled.txt", "w", encoding="utf-8") as f:
|
||||
f.write(title)
|
||||
f.write("\n")
|
||||
f.write(changelog)
|
||||
print("changelogPlainTitledFile=" + dir + "whatsnew_titled.txt")
|
||||
|
||||
print("changelogTitle=" + title)
|
||||
|
||||
# plain text changelog, max 500 chars - Google Play
|
||||
with open(dir + "whatsnew-pl-PL", "w", encoding="utf-8") as f:
|
||||
changelog_lines = changelog.split("\n")
|
||||
changelog = ""
|
||||
for line in changelog_lines:
|
||||
if len(changelog) + len(line) < 500:
|
||||
changelog += "\n" + line
|
||||
changelog = changelog.strip()
|
||||
f.write(changelog)
|
||||
|
||||
print("changelogPlainFile=" + dir + "whatsnew-pl-PL")
|
||||
|
||||
# markdown changelog - Discord webhook
|
||||
(_, changelog) = get_changelog(project_dir, format="markdown")
|
||||
with open(dir + "whatsnew.md", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("changelogMarkdownFile=" + dir + "whatsnew.md")
|
||||
|
||||
# html changelog - version info in DB
|
||||
(_, changelog) = get_changelog(project_dir, format="html")
|
||||
with open(dir + "whatsnew.html", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("changelogHtmlFile=" + dir + "whatsnew.html")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="plain", max_lines=10)
|
||||
with open(dir + "commit_log.txt", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("commitLogPlainFile=" + dir + "commit_log.txt")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="markdown", max_lines=10)
|
||||
with open(dir + "commit_log.md", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("commitLogMarkdownFile=" + dir + "commit_log.md")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="html", max_lines=10)
|
||||
with open(dir + "commit_log.html", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("commitLogHtmlFile=" + dir + "commit_log.html")
|
26
.github/utils/find_artifacts.py
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
||||
from _utils import get_project_dir
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: rename_artifacts.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
files = glob.glob(f"{project_dir}/app/release/*.*")
|
||||
for file in files:
|
||||
file_relative = file.replace(project_dir + "/", "")
|
||||
if "-aligned.apk" in file:
|
||||
os.unlink(file)
|
||||
elif "-signed.apk" in file:
|
||||
new_file = file.replace("-signed.apk", ".apk")
|
||||
if os.path.isfile(new_file):
|
||||
os.unlink(new_file)
|
||||
os.rename(file, new_file)
|
||||
elif ".apk" in file or ".aab" in file:
|
||||
print("signedReleaseFile=" + file)
|
||||
print("signedReleaseFileRelative=" + file_relative)
|
141
.github/utils/save_version.py
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import mysql.connector as mysql
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from _utils import get_changelog, get_commit_log, get_project_dir, read_gradle_version
|
||||
|
||||
|
||||
def save_version(
|
||||
project_dir: str,
|
||||
db_host: str,
|
||||
db_user: str,
|
||||
db_pass: str,
|
||||
db_name: str,
|
||||
apk_server_release: str,
|
||||
apk_server_nightly: str,
|
||||
):
|
||||
db = mysql.connect(
|
||||
host=db_host,
|
||||
user=db_user,
|
||||
password=db_pass,
|
||||
database=db_name,
|
||||
auth_plugin="mysql_native_password",
|
||||
)
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
(_, changelog) = get_changelog(project_dir, format="html")
|
||||
|
||||
types = ["dev", "beta", "nightly", "daily", "rc", "release"]
|
||||
build_type = [x for x in types if x in version_name]
|
||||
build_type = build_type[0] if build_type else "release"
|
||||
|
||||
if "+nightly." in version_name or "+daily." in version_name:
|
||||
changelog = get_commit_log(project_dir, format="html")
|
||||
build_type = "nightly"
|
||||
elif "-dev" in version_name:
|
||||
build_type = "dev"
|
||||
elif "-beta." in version_name:
|
||||
build_type = "beta"
|
||||
elif "-rc." in version_name:
|
||||
build_type = "rc"
|
||||
|
||||
build_date = int(time())
|
||||
apk_name = None
|
||||
bundle_name_play = None
|
||||
|
||||
files = glob.glob(f"{project_dir}/app/release/*.*")
|
||||
output_apk = f"Edziennik_{version_name}_official.apk"
|
||||
output_aab_play = f"Edziennik_{version_name}_play.aab"
|
||||
for file in files:
|
||||
if output_apk in file:
|
||||
build_date = int(os.stat(file).st_mtime)
|
||||
apk_name = output_apk
|
||||
if output_aab_play in file:
|
||||
build_date = int(os.stat(file).st_mtime)
|
||||
bundle_name_play = output_aab_play
|
||||
|
||||
build_date = datetime.fromtimestamp(
|
||||
build_date,
|
||||
tz=ZoneInfo("Europe/Warsaw"),
|
||||
).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
if build_type in ["nightly", "daily"]:
|
||||
download_url = apk_server_nightly + apk_name if apk_name else None
|
||||
else:
|
||||
# download_url = apk_server_release + apk_name if apk_name else None
|
||||
download_url = (
|
||||
f"https://github.com/szkolny-eu/szkolny-android/releases/download/v{version_name}/{apk_name}"
|
||||
if apk_name
|
||||
else None
|
||||
)
|
||||
if download_url:
|
||||
print("downloadUrl=" + download_url)
|
||||
|
||||
cols = [
|
||||
"versionCode",
|
||||
"versionName",
|
||||
"releaseDate",
|
||||
"releaseNotes",
|
||||
"releaseType",
|
||||
"downloadUrl",
|
||||
"apkName",
|
||||
"bundleNamePlay",
|
||||
]
|
||||
updated = {
|
||||
"versionCode": version_code,
|
||||
"downloadUrl": download_url,
|
||||
"apkName": apk_name,
|
||||
"bundleNamePlay": bundle_name_play,
|
||||
}
|
||||
|
||||
values = [
|
||||
version_code,
|
||||
version_name,
|
||||
build_date,
|
||||
changelog,
|
||||
build_type,
|
||||
download_url,
|
||||
apk_name,
|
||||
bundle_name_play,
|
||||
]
|
||||
values.extend(val for val in updated.values() if val)
|
||||
|
||||
updated = ", ".join(f"{col} = %s" for (col, val) in updated.items() if val)
|
||||
|
||||
sql = f"INSERT INTO updates ({', '.join(cols)}) VALUES ({'%s, ' * (len(cols) - 1)}%s) ON DUPLICATE KEY UPDATE {updated};"
|
||||
|
||||
c = db.cursor()
|
||||
c.execute(sql, tuple(values))
|
||||
db.commit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: save_version.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
load_dotenv()
|
||||
DB_HOST = os.getenv("DB_HOST")
|
||||
DB_USER = os.getenv("DB_USER")
|
||||
DB_PASS = os.getenv("DB_PASS")
|
||||
DB_NAME = os.getenv("DB_NAME")
|
||||
APK_SERVER_RELEASE = os.getenv("APK_SERVER_RELEASE")
|
||||
APK_SERVER_NIGHTLY = os.getenv("APK_SERVER_NIGHTLY")
|
||||
|
||||
save_version(
|
||||
project_dir,
|
||||
DB_HOST,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
DB_NAME,
|
||||
APK_SERVER_RELEASE,
|
||||
APK_SERVER_NIGHTLY,
|
||||
)
|
82
.github/utils/sign.py
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from _get_password import get_password
|
||||
from _utils import get_project_dir, read_gradle_version
|
||||
|
||||
|
||||
def sign(
|
||||
project_dir: str,
|
||||
version_name: str,
|
||||
version_code: int,
|
||||
password: str,
|
||||
iv: bytes,
|
||||
commit: bool = False,
|
||||
):
|
||||
SIGNING_PATH = f"{project_dir}/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt"
|
||||
CPP_PATH = f"{project_dir}/app/src/main/cpp/szkolny-signing.cpp"
|
||||
|
||||
with open(SIGNING_PATH, "r") as f:
|
||||
signing = f.read()
|
||||
|
||||
with open(CPP_PATH, "r") as f:
|
||||
cpp = f.read()
|
||||
|
||||
SIGNING_REGEX = r"\$param1\..*\.\$param2"
|
||||
CPP_REGEX = r"(?s)/\*.+?toys AES_IV\[16\] = {.+?};"
|
||||
|
||||
SIGNING_FORMAT = "$param1.{}.$param2"
|
||||
CPP_FORMAT = "/*{}*/\nstatic toys AES_IV[16] = {{\n\t{} }};"
|
||||
|
||||
iv_hex = " ".join(["{:02x}".format(x) for x in iv])
|
||||
iv_cpp = ", ".join(["0x{:02x}".format(x) for x in iv])
|
||||
|
||||
signing = re.sub(SIGNING_REGEX, SIGNING_FORMAT.format(password), signing)
|
||||
cpp = re.sub(CPP_REGEX, CPP_FORMAT.format(iv_hex, iv_cpp), cpp)
|
||||
|
||||
with open(SIGNING_PATH, "w") as f:
|
||||
f.write(signing)
|
||||
|
||||
with open(CPP_PATH, "w") as f:
|
||||
f.write(cpp)
|
||||
|
||||
if commit:
|
||||
os.chdir(project_dir)
|
||||
os.system("git add .")
|
||||
os.system(
|
||||
f'git commit -m "[{version_name}] Update build.gradle, signing and changelog."'
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: sign.py <project dir> [commit]")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
load_dotenv()
|
||||
DB_HOST = os.getenv("DB_HOST")
|
||||
DB_USER = os.getenv("DB_USER")
|
||||
DB_PASS = os.getenv("DB_PASS")
|
||||
DB_NAME = os.getenv("DB_NAME")
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
(password, iv) = get_password(
|
||||
version_name, version_code, DB_HOST, DB_USER, DB_PASS, DB_NAME
|
||||
)
|
||||
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
sign(
|
||||
project_dir,
|
||||
version_name,
|
||||
version_code,
|
||||
password,
|
||||
iv,
|
||||
commit="commit" in sys.argv,
|
||||
)
|
119
.github/utils/webhook_discord.py
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from _utils import get_changelog, get_commit_log, get_project_dir, read_gradle_version
|
||||
|
||||
|
||||
def post_webhook(
|
||||
project_dir: str,
|
||||
apk_file: str,
|
||||
download_url: str,
|
||||
webhook_release: str,
|
||||
webhook_testing: str,
|
||||
):
|
||||
(_, version_name) = read_gradle_version(project_dir)
|
||||
|
||||
types = ["dev", "beta", "nightly", "daily", "rc", "release"]
|
||||
build_type = [x for x in types if x in version_name]
|
||||
build_type = build_type[0] if build_type else None
|
||||
|
||||
testing = ["dev", "beta", "nightly", "daily"]
|
||||
testing = build_type in testing
|
||||
|
||||
if testing:
|
||||
build_date = int(os.stat(apk_file).st_mtime)
|
||||
if build_date:
|
||||
build_date = datetime.fromtimestamp(
|
||||
build_date,
|
||||
tz=ZoneInfo("Europe/Warsaw"),
|
||||
).strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
# untagged release, get commit log
|
||||
if build_type in ["nightly", "daily"]:
|
||||
changelog = get_commit_log(project_dir, format="markdown", max_lines=5)
|
||||
else:
|
||||
changelog = get_changelog(project_dir, format="markdown")
|
||||
|
||||
webhook = get_webhook_testing(
|
||||
version_name, build_type, changelog, download_url, build_date
|
||||
)
|
||||
requests.post(url=webhook_testing, json=webhook)
|
||||
else:
|
||||
changelog = get_changelog(project_dir, format="markdown")
|
||||
webhook = get_webhook_release(version_name, changelog, download_url)
|
||||
requests.post(url=webhook_release, json=webhook)
|
||||
|
||||
|
||||
def get_webhook_release(version_name: str, changelog: str, download_url: str):
|
||||
(title, content) = changelog
|
||||
return {
|
||||
"content": (
|
||||
f"__**{title}**__\n{content}\n[Szkolny.eu {version_name}]({download_url})"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def get_webhook_testing(
|
||||
version_name: str,
|
||||
build_type: str,
|
||||
changelog: str,
|
||||
download_url: str,
|
||||
build_date: str,
|
||||
):
|
||||
return {
|
||||
"embeds": [
|
||||
{
|
||||
"title": f"Nowa wersja {build_type} aplikacji Szkolny.eu",
|
||||
"description": f"Dostępna jest nowa wersja testowa **{build_type}**.",
|
||||
"color": 2201331,
|
||||
"fields": [
|
||||
{
|
||||
"name": f"Wersja `{version_name}`",
|
||||
"value": (
|
||||
f"[Pobierz .APK]({download_url})"
|
||||
if download_url
|
||||
else "*Pobieranie niedostępne*"
|
||||
),
|
||||
"inline": False,
|
||||
},
|
||||
{
|
||||
"name": "Data kompilacji",
|
||||
"value": build_date or "-",
|
||||
"inline": False,
|
||||
},
|
||||
{
|
||||
"name": "Ostatnie zmiany",
|
||||
"value": changelog or "-",
|
||||
"inline": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: webhook_discord.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
load_dotenv()
|
||||
APK_FILE = os.getenv("APK_FILE")
|
||||
DOWNLOAD_URL = os.getenv("DOWNLOAD_URL")
|
||||
WEBHOOK_RELEASE = os.getenv("WEBHOOK_RELEASE")
|
||||
WEBHOOK_TESTING = os.getenv("WEBHOOK_TESTING")
|
||||
|
||||
post_webhook(
|
||||
project_dir,
|
||||
APK_FILE,
|
||||
DOWNLOAD_URL,
|
||||
WEBHOOK_RELEASE,
|
||||
WEBHOOK_TESTING,
|
||||
)
|
195
.github/workflows/_build.yml
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
name: "[reusable] Szkolny.eu Build"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
nightly:
|
||||
type: boolean
|
||||
default: false
|
||||
build-apk:
|
||||
type: boolean
|
||||
default: false
|
||||
build-aab:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
release-ssh:
|
||||
type: boolean
|
||||
default: false
|
||||
release-github:
|
||||
type: boolean
|
||||
default: false
|
||||
release-firebase:
|
||||
type: boolean
|
||||
default: false
|
||||
release-google-play:
|
||||
type: boolean
|
||||
default: false
|
||||
release-discord:
|
||||
type: boolean
|
||||
default: false
|
||||
secrets:
|
||||
APK_SERVER_NIGHTLY:
|
||||
APK_SERVER_RELEASE:
|
||||
DB_HOST:
|
||||
DB_NAME:
|
||||
DB_PASS:
|
||||
DB_USER:
|
||||
FIREBASE_APP_ID:
|
||||
FIREBASE_GROUPS_NIGHTLY:
|
||||
FIREBASE_GROUPS_RELEASE:
|
||||
FIREBASE_SERVICE_ACCOUNT_JSON:
|
||||
KEY_ALIAS_PASSWORD:
|
||||
KEY_ALIAS:
|
||||
KEY_STORE_PASSWORD:
|
||||
KEY_STORE:
|
||||
PLAY_RELEASE_TRACK:
|
||||
PLAY_SERVICE_ACCOUNT_JSON:
|
||||
SSH_IP:
|
||||
SSH_KEY:
|
||||
SSH_PATH_NIGHTLY:
|
||||
SSH_PATH_RELEASE:
|
||||
SSH_USERNAME:
|
||||
WEBHOOK_RELEASE:
|
||||
WEBHOOK_TESTING:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Setup JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install Python packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
python-dotenv
|
||||
pycryptodome
|
||||
mysql-connector-python
|
||||
requests
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
- name: Bump nightly version
|
||||
if: ${{ inputs.nightly }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/bump_nightly.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Write signing passwords and keystore
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
KEY_STORE: ${{ secrets.KEY_STORE }}
|
||||
run: |
|
||||
python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit >> $GITHUB_OUTPUT
|
||||
echo $KEY_STORE | base64 --decode > keystore.jks
|
||||
- name: Clean build artifacts
|
||||
run: |
|
||||
rm -rf app/release/*
|
||||
rm -rf app/build/outputs/apk/*
|
||||
rm -rf app/build/outputs/bundle/*
|
||||
|
||||
- name: Build app with Gradle
|
||||
if: ${{ inputs.build-apk || inputs.build-aab }}
|
||||
run: |
|
||||
chmod +x ./gradlew
|
||||
./gradlew \
|
||||
${{ inputs.build-apk && 'assembleOfficialRelease' || '' }} \
|
||||
${{ inputs.build-aab && 'bundlePlayRelease' || '' }} \
|
||||
-P android.injected.signing.store.file=${{ github.workspace }}/keystore.jks \
|
||||
-P android.injected.signing.store.password=${{ secrets.KEY_STORE_PASSWORD }} \
|
||||
-P android.injected.signing.key.alias=${{ secrets.KEY_ALIAS }} \
|
||||
-P android.injected.signing.key.password=${{ secrets.KEY_ALIAS_PASSWORD }}
|
||||
|
||||
- name: Upload release to server
|
||||
if: ${{ inputs.release-ssh }}
|
||||
uses: easingthemes/ssh-deploy@v2.1.6
|
||||
env:
|
||||
REMOTE_HOST: ${{ secrets.SSH_IP }}
|
||||
REMOTE_USER: ${{ secrets.SSH_USERNAME }}
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
|
||||
SOURCE: app/release/
|
||||
TARGET: ${{ inputs.nightly && secrets.SSH_PATH_NIGHTLY || secrets.SSH_PATH_RELEASE }}
|
||||
|
||||
- name: Find signed artifacts
|
||||
id: artifacts
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/find_artifacts.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Extract release changelogs
|
||||
id: changelog
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Save version to database
|
||||
id: save
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/save_version.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Release on GitHub
|
||||
if: ${{ inputs.release-github }}
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.changelogTitle }}
|
||||
body_path: ${{ steps.changelog.outputs.changelogMarkdownFile }}
|
||||
files: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Distribute to App Distribution
|
||||
if: ${{ inputs.release-firebase }}
|
||||
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||
with:
|
||||
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}
|
||||
file: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
groups: ${{ inputs.nightly && secrets.FIREBASE_GROUPS_NIGHTLY || secrets.FIREBASE_GROUPS_RELEASE }}
|
||||
releaseNotesFile: ${{ inputs.nightly && steps.changelog.outputs.commitLogPlainFile || steps.changelog.outputs.changelogPlainTitledFile }}
|
||||
|
||||
- name: Publish AAB to Google Play
|
||||
if: ${{ inputs.release-google-play }}
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
|
||||
packageName: pl.szczodrzynski.edziennik
|
||||
releaseFiles: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
releaseName: ${{ steps.changelog.outputs.appVersionName }}
|
||||
track: ${{ secrets.PLAY_RELEASE_TRACK }}
|
||||
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
|
||||
status: completed
|
||||
|
||||
- name: Post Discord webhook
|
||||
if: ${{ inputs.release-discord }}
|
||||
env:
|
||||
APK_FILE: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
DOWNLOAD_URL: ${{ steps.save.outputs.downloadUrl }}
|
||||
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
|
||||
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||
path: |
|
||||
app/release/whatsnew*/
|
||||
app/release/*.apk
|
||||
app/release/*.aab
|
||||
app/release/*.json
|
||||
app/release/*.txt
|
13
.github/workflows/push-master.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name: Push (master)
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
jobs:
|
||||
build:
|
||||
name: Build for Google Play (AAB)
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
build-aab: true
|
||||
release-ssh: true
|
||||
release-google-play: true
|
||||
secrets: inherit
|
15
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v*.*.*"]
|
||||
jobs:
|
||||
build:
|
||||
name: Build release (APK)
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
build-apk: true
|
||||
release-ssh: true
|
||||
release-github: true
|
||||
release-firebase: true
|
||||
release-discord: true
|
||||
secrets: inherit
|
42
.github/workflows/schedule-dispatch.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Schedule/dispatch
|
||||
on:
|
||||
schedule:
|
||||
# 23:30 UTC, 0:30 or 1:30 CET/CEST
|
||||
- cron: "30 23 * * *"
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
check:
|
||||
name: Check new changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
hasNewChanges: ${{ steps.nightly.outputs.hasNewChanges }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
requests
|
||||
- name: Check new changes
|
||||
id: nightly
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/check_nightly.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
name: Build nightly release (APK)
|
||||
needs:
|
||||
- check
|
||||
if: ${{ needs.check.outputs.hasNewChanges == 'true' }}
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
nightly: true
|
||||
build-apk: true
|
||||
release-ssh: true
|
||||
release-firebase: true
|
||||
release-discord: true
|
||||
secrets: inherit
|
1
.gitignore
vendored
@ -265,3 +265,4 @@ fabric.properties
|
||||
# End of https://www.toptal.com/developers/gitignore/api/android,androidstudio,gradle,java,kotlin
|
||||
|
||||
signatures/
|
||||
.idea/*.xml
|
||||
|
37
.idea/codeStyles/Project.xml
generated
@ -1,8 +1,33 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="LAYOUT_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="MANIFEST_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="OTHER_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="ALLOW_TRAILING_COMMA" value="true" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
<option name="SMART_TABS" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
@ -15,6 +40,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -25,6 +51,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -36,6 +63,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -46,6 +74,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -56,6 +85,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -66,6 +96,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -76,6 +107,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -87,6 +119,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -98,6 +131,7 @@
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
@ -109,6 +143,9 @@
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="2" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
6
.idea/copyright/Antoni.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="Copyright (c) Antoni Czaplicki &#36;{today.year}-&#36;{today.month}-&#36;{today.day}. " />
|
||||
<option name="myName" value="Antoni" />
|
||||
</copyright>
|
||||
</component>
|
4
.idea/dictionaries/Kuba.xml
generated
@ -4,7 +4,10 @@
|
||||
<w>autoryzacji</w>
|
||||
<w>ciasteczko</w>
|
||||
<w>csrf</w>
|
||||
<w>daynight</w>
|
||||
<w>edziennik</w>
|
||||
<w>eggfall</w>
|
||||
<w>elearning</w>
|
||||
<w>gson</w>
|
||||
<w>hebe</w>
|
||||
<w>idziennik</w>
|
||||
@ -12,6 +15,7 @@
|
||||
<w>synergia</w>
|
||||
<w>szczodrzyński</w>
|
||||
<w>szkolny</w>
|
||||
<w>usos</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
9
.idea/discord.xml
generated
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
</component>
|
||||
<component name="ProjectNotificationSettings">
|
||||
<option name="askShowProject" value="false" />
|
||||
</component>
|
||||
</project>
|
6
.idea/kotlinc.xml
generated
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Kotlin2JvmCompilerArguments">
|
||||
<option name="jvmTarget" value="1.8" />
|
||||
</component>
|
||||
</project>
|
13
.idea/runConfigurations.xml
generated
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<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.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
38
README.md
@ -1,22 +1,24 @@
|
||||
# Szkolny.eu
|
||||
|
||||
Nieoficjalna aplikacja do obsługi najpopularniejszych dzienników elektronicznych w Polsce.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
[](https://szkolny.eu/discord)
|
||||
[](https://szkolny.eu/)
|
||||
[](https://szkolny.eu/facebook)
|
||||
|
||||

|
||||

|
||||
[](https://github.com/szkolny-eu/szkolny-android/releases/latest)
|
||||

|
||||
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/release.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/push-master.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/schedule-dispatch.yml)
|
||||
|
||||
</div>
|
||||
|
||||
## Ważna informacja
|
||||
|
||||
Jak zapewne już wiecie, we wrześniu 2020r. **firma Librus zabroniła nam** publikowania w sklepie Google Play naszej aplikacji z obsługą dziennika Librus® Synergia. Prowadziliśmy rozmowy, aby **umożliwić Wam wygodny, bezpłatny dostęp do Waszych ocen, wiadomości, zadań domowych**, jednak oczekiwania firmy Librus zdecydowanie przekroczyły wszelkie nasze możliwości finansowe. Mając na uwadze powyższe względy, zdecydowaliśmy się opublikować kod źródłowy aplikacji Szkolny.eu. Liczymy, że dzięki temu aplikacja będzie mogła dalej funkcjonować, być rozwijana, pomagając Wam w czasie zdalnego nauczania i przez kolejne lata nauki.
|
||||
Jak zapewne już wiecie, we wrześniu 2020 r. **firma Librus zabroniła nam** publikowania w sklepie Google Play naszej aplikacji z obsługą dziennika Librus® Synergia. Prowadziliśmy rozmowy, aby **umożliwić Wam wygodny, bezpłatny dostęp do Waszych ocen, wiadomości, zadań domowych**, jednak oczekiwania firmy Librus zdecydowanie przekroczyły wszelkie nasze możliwości finansowe. Mając na uwadze powyższe względy, zdecydowaliśmy się opublikować kod źródłowy aplikacji Szkolny.eu. Liczymy, że dzięki temu aplikacja będzie mogła dalej funkcjonować, być rozwijana, pomagając Wam w czasie zdalnego nauczania i przez kolejne lata nauki.
|
||||
|
||||
__Zachęcamy do [przeczytania całej informacji](https://szkolny.eu/informacja) na naszej stronie.__
|
||||
|
||||
@ -30,17 +32,17 @@ Szkolny.eu jest nieoficjalną aplikacją, umożliwiającą rodzicom i uczniom do
|
||||
|
||||
- plan lekcji, terminarz, oceny, wiadomości, zadania domowe, uwagi, frekwencja
|
||||
- wygodne **widgety** na ekran główny
|
||||
- łatwa komunikacja z nauczycielami - **odbieranie, wyszukiwanie i wysyłanie wiadomości**
|
||||
- łatwa komunikacja z nauczycielami — **odbieranie, wyszukiwanie i wysyłanie wiadomości**
|
||||
- pobieranie **załączników wiadomości i zadań domowych**
|
||||
- **powiadomienia** o nowych informacjach na telefonie lub na komputerze
|
||||
- organizacja zadań domowych i sprawdzianów - łatwe oznaczanie jako wykonane
|
||||
- organizacja zadań domowych i sprawdzianów — łatwe oznaczanie jako wykonane
|
||||
- obliczanie **średniej ocen** ze wszystkich przedmiotów, oceny proponowane i końcowe
|
||||
- Symulator edycji ocen - obliczanie średniej z przedmiotu po zmianie dowolnych jego ocen
|
||||
- Symulator edycji ocen — obliczanie średniej z przedmiotu po zmianie dowolnych jego ocen
|
||||
- **dodawanie własnych wydarzeń** i zadań do terminarza
|
||||
- nowoczesny i intuicyjny interfejs użytkownika
|
||||
- **obsługa wielu profili** uczniów - jeżeli jesteś Rodzicem, możesz skonfigurować wszystkie swoje konta uczniowskie i łatwo między nimi przełączać
|
||||
- **obsługa wielu profili** uczniów — jeżeli jesteś Rodzicem, możesz skonfigurować wszystkie swoje konta uczniowskie i łatwo między nimi przełączać
|
||||
- opcja **automatycznej synchronizacji** z E-dziennikiem
|
||||
- opcja Ciszy nocnej - nigdy więcej budzących Cię dźwięków z telefonu
|
||||
- opcja Ciszy nocnej — nigdy więcej budzących Cię dźwięków z telefonu
|
||||
|
||||
[Zobacz porównanie funkcji z innymi aplikacjami](https://szkolny.eu/funkcje)
|
||||
|
||||
@ -53,7 +55,7 @@ Najnowsze wersje możesz pobrać z Google Play lub bezpośrednio z naszej strony
|
||||
|
||||
### Kompilacja
|
||||
|
||||
Aby uruchomić aplikację "ze źródeł" należy użyć Android Studio w wersji co najmniej 4.2 Beta 6. Wersja `debug` może wtedy zostać zainstalowana np. na emulatorze Androida.
|
||||
Aby uruchomić aplikację „ze źródeł” należy użyć Android Studio w wersji co najmniej 4.2 Beta 6. Wersja `debug` może wtedy zostać zainstalowana np. na emulatorze Androida.
|
||||
|
||||
Aby zbudować wersję produkcyjną, tzn. `release` należy użyć wariantu `mainRelease` oraz podpisać wyjściowy plik .APK sygnaturą w wersji V1 i V2.
|
||||
|
||||
@ -68,15 +70,15 @@ __Jeśli masz jakieś pytania, zapraszamy na [nasz serwer Discord](https://szkol
|
||||
## Licencja
|
||||
|
||||
Szkolny.eu publikowany jest na licencji [GNU GPLv3](LICENSE). W szczególności, deweloper:
|
||||
- może modyfikować oraz usprawniać kod aplikacji
|
||||
- może dystrybuować wersje produkcyjne
|
||||
- musi opublikować wszelkie wprowadzone zmiany, tzn. publiczny fork tego repozytorium
|
||||
- nie może zmieniać licencji ani copyrightu aplikacji
|
||||
- Może modyfikować oraz usprawniać kod aplikacji
|
||||
- Może dystrybuować wersje produkcyjne
|
||||
- Musi opublikować wszelkie wprowadzone zmiany, tzn. publiczny fork tego repozytorium
|
||||
- Nie może zmieniać licencji ani copyrightu aplikacji
|
||||
|
||||
Dodatkowo:
|
||||
- zabronione jest modyfikowanie lub usuwanie kodu odpowiedzialnego za zgodność wersji produkcyjnych z licencją
|
||||
- Zabronione jest modyfikowanie lub usuwanie kodu odpowiedzialnego za zgodność wersji produkcyjnych z licencją.
|
||||
|
||||
- **wersje skompilowane nie mogą być dystrybuowane za pomocą Google Play oraz żadnej platformy, na której istnieje oficjalna wersja aplikacji**
|
||||
- **Wersje skompilowane nie mogą być dystrybuowane za pomocą Google Play oraz żadnej platformy, na której istnieje oficjalna wersja aplikacji**.
|
||||
|
||||
**Autorzy aplikacji nie biorą odpowiedzialności za używanie aplikacji, modyfikowanie oraz dystrybuowanie.**
|
||||
|
||||
|
172
app/build.gradle
@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
|
||||
@ -9,8 +10,10 @@ apply from: 'git-info.gradle'
|
||||
android {
|
||||
compileSdkVersion setup.compileSdk
|
||||
|
||||
namespace "pl.szczodrzynski.edziennik"
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'pl.szczodrzynski.edziennik'
|
||||
applicationId "pl.szczodrzynski.edziennik"
|
||||
minSdkVersion setup.minSdk
|
||||
targetSdkVersion setup.targetSdk
|
||||
|
||||
@ -18,9 +21,12 @@ android {
|
||||
versionName release.versionName
|
||||
|
||||
buildConfigField "java.util.Map<String, String>", "GIT_INFO", gitInfoMap
|
||||
buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis())
|
||||
buildConfigField "String", "VERSION_BASE", "\"${release.versionName}\""
|
||||
|
||||
manifestPlaceholders = [
|
||||
buildTimestamp: String.valueOf(System.currentTimeMillis())
|
||||
]
|
||||
|
||||
multiDexEnabled = true
|
||||
|
||||
externalNativeBuild {
|
||||
@ -28,12 +34,26 @@ android {
|
||||
cppFlags "-std=c++11"
|
||||
}
|
||||
}
|
||||
|
||||
kapt {
|
||||
arguments {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
|
||||
correctErrorTypes = true
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
getIsDefault().set(true)
|
||||
minifyEnabled = false
|
||||
applicationIdSuffix = ".debug"
|
||||
manifestPlaceholders = [
|
||||
buildTimestamp: "0"
|
||||
]
|
||||
}
|
||||
|
||||
release {
|
||||
minifyEnabled = true
|
||||
shrinkResources = true
|
||||
@ -41,51 +61,82 @@ android {
|
||||
proguardFiles fileTree('proguard').asList().toArray()
|
||||
}
|
||||
}
|
||||
flavorDimensions "platform"
|
||||
|
||||
flavorDimensions += "platform"
|
||||
|
||||
productFlavors {
|
||||
main {
|
||||
versionName gitInfo.versionHuman
|
||||
unofficial {
|
||||
getIsDefault().set(true)
|
||||
versionName "${release.versionName}-${gitInfo.versionSuffix}"
|
||||
}
|
||||
|
||||
official {}
|
||||
play {}
|
||||
}
|
||||
|
||||
variantFilter { variant ->
|
||||
def flavors = variant.flavors*.name
|
||||
setIgnore(variant.buildType.name == "debug" && !flavors.contains("main"))
|
||||
setIgnore(variant.buildType.name == "debug" && !flavors.contains("unofficial") || flavors.contains("main"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
unofficial {
|
||||
java.srcDirs = ["src/main/java", "src/play-not/java"]
|
||||
manifest.srcFile("src/play-not/AndroidManifest.xml")
|
||||
}
|
||||
|
||||
official {
|
||||
java.srcDirs = ["src/main/java", "src/play-not/java"]
|
||||
manifest.srcFile("src/play-not/AndroidManifest.xml")
|
||||
}
|
||||
|
||||
play {
|
||||
java.srcDirs = ["src/main/java", "src/play/java"]
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
lintOptions {
|
||||
checkReleaseBuilds = false
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
freeCompilerArgs += "-Xcontext-receivers"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/library-core_release.kotlin_module'
|
||||
resources {
|
||||
excludes += ['META-INF/library-core_release.kotlin_module']
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "src/main/cpp/CMakeLists.txt"
|
||||
version "3.10.2"
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
}
|
||||
|
||||
tasks.whenTaskAdded { task ->
|
||||
if (!task.name.endsWith("Release") && !task.name.endsWith("ReleaseWithR8"))
|
||||
if (!(task.name == "assembleUnofficialRelease" || task.name == "assembleOfficialRelease" || task.name == "signPlayReleaseBundle"))
|
||||
return
|
||||
|
||||
def renameTaskName = "rename${task.name.capitalize()}"
|
||||
|
||||
def flavor = ""
|
||||
@ -95,14 +146,22 @@ tasks.whenTaskAdded { task ->
|
||||
flavor = task.name.substring("assemble".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
if (task.name.startsWith("minify"))
|
||||
flavor = task.name.substring("minify".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
if (task.name.startsWith("sign"))
|
||||
flavor = task.name.substring("sign".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
|
||||
if (flavor != "") {
|
||||
tasks.create(renameTaskName, Copy) {
|
||||
from file("${projectDir}/${flavor}/release/"), file("${buildDir}/outputs/mapping/${flavor}Release/")
|
||||
include "*.aab", "*.apk", "mapping.txt", "output-metadata.json"
|
||||
tasks.register(renameTaskName, Copy) {
|
||||
dependsOn(task.name)
|
||||
duplicatesStrategy DuplicatesStrategy.FAIL
|
||||
from file("${projectDir}/${flavor}/release/"),
|
||||
file("${projectDir}/build/outputs/apk/${flavor}/release/"),
|
||||
file("${projectDir}/build/outputs/mapping/${flavor}Release/"),
|
||||
file("${projectDir}/build/outputs/bundle/${flavor}Release/")
|
||||
include "*-release.aab", "*-release.apk", "mapping.txt", "output-metadata.json"
|
||||
destinationDir file("${projectDir}/release/")
|
||||
rename ".+?\\.(.+)", "Edziennik_${android.defaultConfig.versionName}_${flavor}." + '$1'
|
||||
}
|
||||
|
||||
task.finalizedBy(renameTaskName)
|
||||
}
|
||||
}
|
||||
@ -112,28 +171,30 @@ dependencies {
|
||||
|
||||
// Language cores
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
implementation "androidx.multidex:multidex:2.0.1"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
|
||||
|
||||
// Android Jetpack
|
||||
implementation "androidx.appcompat:appcompat:1.2.0"
|
||||
implementation "androidx.appcompat:appcompat:1.7.0"
|
||||
implementation "androidx.cardview:cardview:1.0.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.3.4"
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "androidx.room:room-runtime:2.2.6"
|
||||
implementation "androidx.work:work-runtime-ktx:2.5.0"
|
||||
kapt "androidx.room:room-compiler:2.2.6"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
||||
implementation "androidx.core:core-ktx:1.13.1"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.2"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
|
||||
implementation "androidx.recyclerview:recyclerview:1.3.2"
|
||||
implementation "androidx.room:room-runtime:2.6.1"
|
||||
implementation "androidx.room:room-ktx:2.6.1"
|
||||
implementation "androidx.work:work-runtime-ktx:2.9.0"
|
||||
kapt "androidx.room:room-compiler:2.6.1"
|
||||
|
||||
// Google design libs
|
||||
implementation "com.google.android.material:material:1.3.0"
|
||||
implementation "com.google.android:flexbox:2.0.1"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "com.google.android.flexbox:flexbox:3.0.0"
|
||||
|
||||
// Play Services/Firebase
|
||||
implementation "com.google.android.gms:play-services-wearable:17.0.0"
|
||||
implementation "com.google.firebase:firebase-core:18.0.2"
|
||||
implementation "com.google.firebase:firebase-crashlytics:17.4.0"
|
||||
implementation "com.google.android.gms:play-services-wearable:18.2.0"
|
||||
implementation("com.google.firebase:firebase-core") { version { strictly "19.0.2" } }
|
||||
implementation "com.google.firebase:firebase-crashlytics:19.0.1"
|
||||
implementation("com.google.firebase:firebase-messaging") { version { strictly "20.1.3" } }
|
||||
|
||||
// OkHttp, Retrofit, Gson, Jsoup
|
||||
@ -141,55 +202,60 @@ dependencies {
|
||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
|
||||
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation "org.jsoup:jsoup:1.13.1"
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation 'org.jsoup:jsoup:1.14.3'
|
||||
implementation "pl.droidsonroids:jspoon:1.3.2"
|
||||
implementation "pl.droidsonroids.retrofit2:converter-jspoon:1.3.2"
|
||||
|
||||
// Szkolny.eu libraries/forks
|
||||
implementation "eu.szkolny:agendacalendarview:1799f8ef47"
|
||||
implementation project(":navlib")
|
||||
implementation "eu.szkolny:android-snowfall:1ca9ea2da3"
|
||||
implementation "eu.szkolny:agendacalendarview:1.0.4"
|
||||
implementation "eu.szkolny:cafebar:5bf0c618de"
|
||||
implementation "eu.szkolny.fslogin:lib:2.0.0"
|
||||
implementation "eu.szkolny:material-about-library:1d5ebaf47c"
|
||||
implementation "eu.szkolny:mhttp:af4b62e6e9"
|
||||
implementation "eu.szkolny:nachos:0e5dfcaceb"
|
||||
implementation "eu.szkolny.selective-dao:annotation:27f8f3f194"
|
||||
implementation "eu.szkolny:ssl-provider:1.0.0"
|
||||
implementation "pl.szczodrzynski:navlib:0.8.0"
|
||||
implementation "eu.szkolny.selective-dao:annotation:6a337f9"
|
||||
officialImplementation "eu.szkolny:ssl-provider:1.0.0"
|
||||
unofficialImplementation "eu.szkolny:ssl-provider:1.0.0"
|
||||
|
||||
implementation "pl.szczodrzynski:numberslidingpicker:2921225f76"
|
||||
implementation "pl.szczodrzynski:recyclertablayout:700f980584"
|
||||
implementation "pl.szczodrzynski:tachyon:551943a6b5"
|
||||
kapt "eu.szkolny.selective-dao:codegen:27f8f3f194"
|
||||
kapt "eu.szkolny.selective-dao:codegen:6a337f9"
|
||||
|
||||
// Iconics & related
|
||||
implementation "com.mikepenz:iconics-core:5.3.0-b01"
|
||||
implementation "com.mikepenz:iconics-views:5.3.0-b01"
|
||||
implementation "com.mikepenz:iconics-core:5.3.2"
|
||||
implementation "com.mikepenz:iconics-views:5.3.2"
|
||||
implementation "com.mikepenz:materialdrawer:9.0.1"
|
||||
implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar"
|
||||
implementation "eu.szkolny:szkolny-font:1.3"
|
||||
implementation 'com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar'
|
||||
implementation "eu.szkolny:szkolny-font:95eabe7"
|
||||
|
||||
// Other dependencies
|
||||
implementation "cat.ereza:customactivityoncrash:2.3.0"
|
||||
implementation "com.applandeo:material-calendar-view:1.5.0"
|
||||
implementation "com.android.volley:volley:1.2.1"
|
||||
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
||||
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2"
|
||||
implementation "com.github.bassaer:chatmessageview:2.0.1"
|
||||
implementation "com.github.CanHub:Android-Image-Cropper:2.2.2"
|
||||
implementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
|
||||
implementation "com.github.jetradarmobile:android-snowfall:1.2.0"
|
||||
implementation "com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31"
|
||||
implementation("com.heinrichreimersoftware:material-intro") { version { strictly "1.5.8" } }
|
||||
implementation "com.hypertrack:hyperlog:0.0.10"
|
||||
implementation "com.github.Applandeo:Material-Calendar-View:15de569cbc" // https://github.com/Applandeo/Material-Calendar-View
|
||||
implementation "com.github.CanHub:Android-Image-Cropper:2.2.2" // https://github.com/CanHub/Android-Image-Cropper
|
||||
implementation "com.github.ChuckerTeam.Chucker:library:3.5.2" // https://github.com/ChuckerTeam/chucker
|
||||
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2" // https://github.com/antonKozyriatskyi/CircularProgressIndicator
|
||||
implementation "com.github.bassaer:chatmessageview:2.0.1" // https://github.com/bassaer/ChatMessageView
|
||||
implementation "com.github.smuyyh:JsonViewer:V1.0.6" // https://github.com/smuyyh/JsonViewer
|
||||
implementation "com.github.underwindfall.PowerPermission:powerpermission-coroutines:1.4.0" // https://github.com/underwindfall/PowerPermission
|
||||
implementation "com.github.underwindfall.PowerPermission:powerpermission:1.4.0" // https://github.com/underwindfall/PowerPermission
|
||||
implementation "com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31" // https://github.com/wulkanowy/uonet-request-signer
|
||||
implementation 'com.jakewharton.timber:timber:5.0.1'
|
||||
implementation "com.jaredrummler:colorpicker:1.1.0"
|
||||
implementation "com.qifan.powerpermission:powerpermission-coroutines:1.3.0"
|
||||
implementation "com.qifan.powerpermission:powerpermission:1.3.0"
|
||||
implementation "com.yuyh.json:jsonviewer:1.0.6"
|
||||
implementation "io.coil-kt:coil:1.1.1"
|
||||
implementation "me.dm7.barcodescanner:zxing:1.9.8"
|
||||
implementation "me.grantland:autofittextview:0.2.1"
|
||||
implementation "me.leolin:ShortcutBadger:1.1.22@aar"
|
||||
implementation "org.greenrobot:eventbus:3.2.0"
|
||||
implementation("com.heinrichreimersoftware:material-intro") { version { strictly "1.5.8" } }
|
||||
implementation("pl.droidsonroids.gif:android-gif-drawable") { version { strictly "1.2.15" } }
|
||||
|
||||
// Debug-only dependencies
|
||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
||||
debugImplementation "com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:v1.0.6"
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.eclipse.jgit:org.eclipse.jgit:5.5.+"
|
||||
@ -84,7 +84,7 @@ private def buildGitInfo() {
|
||||
.stream()
|
||||
.map {
|
||||
it.name + "(" + it.URIs.stream()
|
||||
.map { it.rawPath }
|
||||
.map { it.rawPath.stripMargin('/').replace(".git", "") }
|
||||
.toArray()
|
||||
.join(", ") + ")"
|
||||
}
|
||||
@ -97,18 +97,17 @@ private def buildGitInfo() {
|
||||
def tag = getLastTag(repo, git, head)
|
||||
def tagName = tag[1]
|
||||
def tagRevCount = tag[2]
|
||||
def versionName = tagName.replace("v", "")
|
||||
|
||||
def result = [
|
||||
hash : head.objectId.name,
|
||||
branch : repo.branch,
|
||||
dirty : dirty,
|
||||
remotes : remotes,
|
||||
unstaged : status.uncommittedChanges.join("; "),
|
||||
tag : tagName,
|
||||
revCount : tagRevCount,
|
||||
version : """$tagName-$tagRevCount-g${head.objectId.name.substring(0, 8)}""" + (dirty ? ".dirty" : ""),
|
||||
versionHuman: """$versionName-${repo.branch.replace("/", "_")}""" + (dirty ? ".dirty" : "")
|
||||
hash : head.objectId.name,
|
||||
branch : repo.branch,
|
||||
dirty : dirty,
|
||||
remotes : remotes,
|
||||
unstaged : status.uncommittedChanges.join("; "),
|
||||
tag : tagName,
|
||||
revCount : tagRevCount,
|
||||
version : """$tagName-$tagRevCount-g${head.objectId.name.substring(0, 8)}""" + (dirty ? ".dirty" : ""),
|
||||
versionSuffix : """${repo.branch.replace("/", "_")}""" + (dirty ? ".dirty" : "")
|
||||
]
|
||||
return result
|
||||
}
|
||||
|
@ -36,6 +36,37 @@
|
||||
"status": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:640759989760:android:4aa71407b25cdc8d",
|
||||
"android_client_info": {
|
||||
"package_name": "pl.szczodrzynski.edziennik.debug"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "640759989760-6f8q00u864lnuh3gh36e8g4cer9lv8pv.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAvq9HMPxulz9ntdAHZ0eZuPf2YQs4nDSU"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
},
|
||||
"ads_service": {
|
||||
"status": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
|
43
app/proguard-rules.pro
vendored
@ -19,23 +19,46 @@
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-keepattributes Signature
|
||||
-keep class android.support.v7.widget.** { *; }
|
||||
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||
-keep class * extends com.google.gson.reflect.TypeToken
|
||||
|
||||
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.enums.* { *; }
|
||||
-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.entity.FeedbackMessage { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.db.entity.Note { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.ui.home.HomeCardModel { *; }
|
||||
-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.notifications.WidgetNotificationsProvider
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||
-keep class pl.szczodrzynski.edziennik.data.config.AppData { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.config.AppData$** { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.core.manager.TextStylingManager$HtmlMode { *; }
|
||||
|
||||
-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 androidx.appcompat.view.menu.StandardMenuPopup { private *; }
|
||||
-keepclassmembernames class androidx.appcompat.view.menu.MenuItemImpl { private *; }
|
||||
|
||||
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
||||
-keepclassmembernames class com.mikepenz.iconics.internal.IconicsViewsAttrsApplier {
|
||||
<fields>;
|
||||
readIconicsTextView(android.content.Context, android.util.AttributeSet, com.mikepenz.iconics.internal.CompoundIconsBundle);
|
||||
getIconicsImageViewDrawable(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclassmembernames class com.mikepenz.iconics.internal.CompoundIconsBundle {
|
||||
setIcons(android.widget.TextView);
|
||||
}
|
||||
|
||||
# for RecyclerTabView
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabLayout { *; }
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabLayout$TabView { *; }
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabIndicatorInterpolator { *; }
|
||||
|
||||
-keep class .R
|
||||
-keep class **.R$* {
|
||||
@ -49,8 +72,19 @@
|
||||
|
||||
-keep class com.google.android.material.tabs.** {*;}
|
||||
|
||||
# Exclude AgendaCalendarView
|
||||
# Preserve generic type information for EventRenderer and its subclasses
|
||||
-keepclassmembers class * extends com.github.tibolte.agendacalendarview.render.EventRenderer {
|
||||
<fields>;
|
||||
<methods>;
|
||||
}
|
||||
|
||||
# Keep the EventRenderer class itself and all its subclasses
|
||||
-keep class com.github.tibolte.agendacalendarview.render.EventRenderer
|
||||
-keep class * extends com.github.tibolte.agendacalendarview.render.EventRenderer
|
||||
|
||||
# ServiceLoader support
|
||||
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
|
||||
|
||||
# Most of volatile fields are updated with AFU and should not be mangled
|
||||
@ -64,9 +98,10 @@
|
||||
|
||||
-keep class pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing { public final byte[] pleaseStopRightNow(java.lang.String, long); }
|
||||
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.ui.login.qr.* { *; }
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
||||
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo$Platform { *; }
|
||||
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.login.LoginInfo$Platform { *; }
|
||||
|
||||
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData { *; }
|
||||
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData$Type { *; }
|
||||
|
2320
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/100.json
Normal file
2348
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/101.json
Normal file
2293
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/97.json
Normal file
2314
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/98.json
Normal file
2314
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/99.json
Normal file
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 874 B |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 24 KiB |
@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="pl.szczodrzynski.edziennik">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
@ -13,22 +11,26 @@
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<!-- 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" />
|
||||
<uses-sdk
|
||||
tools:overrideLibrary="com.qifan.powerpermission.coroutines, com.qifan.powerpermission.core, com.mikepenz:materialdrawer, com.mikepenz.iconics.typeface.library.navlibfont, androidx.appcompat.resources, androidx.appcompat, com.google.android.gms.wearable, com.google.android.gms.base, com.google.firebase.crashlytics, com.google.firebase.sessions, com.google.firebase.ktx, com.google.firebase, com.google.android.gms.tasks, com.google.android.gms.common, com.google.firebase.components" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_descriptor"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:icon="@mipmap/ic_launcher_v5"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.Dark"
|
||||
android:theme="@style/AppTheme.M3.Blue"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<meta-data android:name="buildTimestamp" android:value="${buildTimestamp}" />
|
||||
|
||||
<!-- __ __ _ _ _ _ _
|
||||
| \/ | (_) /\ | | (_) (_) |
|
||||
| \ / | __ _ _ _ __ / \ ___| |_ ___ ___| |_ _ _
|
||||
@ -39,8 +41,8 @@
|
||||
|___/ -->
|
||||
<activity android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:exported="true"
|
||||
android:theme="@style/SplashTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -64,14 +66,16 @@
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:excludeFromRecents="true"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/AppTheme.Dark.NoDisplay">
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.M3.NoDisplay">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- TIMETABLE -->
|
||||
<receiver android:name=".ui.widgets.timetable.WidgetTimetableProvider"
|
||||
android:label="@string/widget_timetable_title">
|
||||
android:label="@string/widget_timetable_title"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@ -80,16 +84,18 @@
|
||||
android:resource="@xml/widget_timetable_info" />
|
||||
</receiver>
|
||||
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" android:foregroundServiceType="dataSync"/>
|
||||
<activity android:name=".ui.widgets.LessonDialogActivity"
|
||||
android:label=""
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:excludeFromRecents="true"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/AppTheme.Dark.NoDisplay" />
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.M3.NoDisplay" />
|
||||
<!-- NOTIFICATIONS -->
|
||||
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
||||
android:label="@string/widget_notifications_title">
|
||||
android:label="@string/widget_notifications_title"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@ -99,10 +105,11 @@
|
||||
android:resource="@xml/widget_notifications_info" />
|
||||
</receiver>
|
||||
<service android:name=".ui.widgets.notifications.WidgetNotificationsService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" android:foregroundServiceType="dataSync"/>
|
||||
<!-- LUCKY NUMBER -->
|
||||
<receiver android:name=".ui.widgets.luckynumber.WidgetLuckyNumberProvider"
|
||||
android:label="@string/widget_lucky_number_title">
|
||||
android:label="@string/widget_lucky_number_title"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@ -119,31 +126,44 @@
|
||||
/ ____ \ (__| |_| |\ V /| | |_| | __/\__ \
|
||||
/_/ \_\___|\__|_| \_/ |_|\__|_|\___||___/
|
||||
-->
|
||||
<activity android:name=".ui.modules.base.CrashActivity"
|
||||
<activity android:name=".ui.main.CrashActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:process=":error_activity"
|
||||
android:exported="false"
|
||||
android:theme="@style/DeadTheme" />
|
||||
<activity android:name=".ui.modules.intro.ChangelogIntroActivity"
|
||||
<activity android:name=".ui.intro.ChangelogIntroActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.Intro" />
|
||||
<activity android:name=".ui.modules.login.LoginActivity"
|
||||
<activity android:name=".ui.login.LoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.Light" />
|
||||
<activity android:name=".ui.modules.home.CounterActivity"
|
||||
android:theme="@style/AppTheme.Black" />
|
||||
<activity android:name=".ui.modules.feedback.FeedbackActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.home.CounterActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.feedback.FeedbackActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.settings.SettingsLicenseActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:theme="@style/AppTheme" />
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name="com.canhub.cropper.CropImageActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Base.Theme.AppCompat" />
|
||||
<activity android:name=".ui.modules.base.BuildInvalidActivity" />
|
||||
<activity android:name=".ui.login.oauth.OAuthLoginActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar" />
|
||||
<activity android:name=".ui.login.recaptcha.RecaptchaActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar" />
|
||||
<activity android:name=".ui.main.BuildInvalidActivity" android:exported="false" />
|
||||
|
||||
<!-- _____ _
|
||||
| __ \ (_)
|
||||
@ -152,18 +172,20 @@
|
||||
| | \ \ __/ (_| __/ |\ V / __/ | \__ \
|
||||
|_| \_\___|\___\___|_| \_/ \___|_| |___/
|
||||
-->
|
||||
<receiver android:name=".receivers.UserPresentReceiver"
|
||||
android:enabled="true">
|
||||
<receiver android:name=".core.receiver.UserPresentReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.USER_PRESENT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".sync.UpdateDownloaderService$DownloadProgressReceiver">
|
||||
<receiver android:name=".sync.UpdateDownloaderService$DownloadProgressReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.SzkolnyReceiver"
|
||||
<receiver android:name=".core.receiver.SzkolnyReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" />
|
||||
@ -177,15 +199,15 @@
|
||||
____) | __/ | \ V /| | (_| __/\__ \
|
||||
|_____/ \___|_| \_/ |_|\___\___||___/
|
||||
-->
|
||||
<service android:name=".data.api.ApiService" />
|
||||
<service android:name=".data.firebase.MyFirebaseService"
|
||||
android:exported="false">
|
||||
<service android:name=".data.api.ApiService" android:foregroundServiceType="dataSync"/>
|
||||
<service android:name=".core.firebase.MyFirebaseService"
|
||||
android:exported="false" android:foregroundServiceType="dataSync">
|
||||
<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" />
|
||||
<service android:name=".sync.UpdateDownloaderService" android:foregroundServiceType="dataSync"/>
|
||||
|
||||
<!--
|
||||
_____ _ _
|
||||
|
@ -1,14 +1,11 @@
|
||||
<h3>Wersja 4.7-rc.1, 2021-04-01</h3>
|
||||
<h3>Wersja 4.14, 2025-02-02</h3>
|
||||
<ul>
|
||||
<li><u>Szkolny.eu jest teraz open source!</u> Zapraszamy na stronę https://szkolny.eu/ po więcej ważnych informacji.</li>
|
||||
<li>Poprawiono wybieranie obrazków (tła nagłówka, tła aplikacji oraz profilu) z dowolnego źródła.</li>
|
||||
<li>Naprawiono zatrzymanie aplikacji na Androidzie 4.4 i starszych.</li>
|
||||
<li>Naprawiono problemy z połączeniem internetowym na Androidzie 4.4 i starszych.</li>
|
||||
<li>Dodano ekran informacji o kompilacji w Ustawieniach.</li>
|
||||
<li>Zaktualizowano ekran licencji open source.</li>
|
||||
<li>Zoptymalizowano wielkość aplikacji.</li>
|
||||
<li>USOS: <b>dodano obsługę ocen</b>.</li>
|
||||
<li>USOS: obliczanie średniej za studia oraz punktów ECTS.</li>
|
||||
<li>USOS: poprawiono brak planu zajęć po rozpoczęciu roku.</li>
|
||||
<li>Wyłączono archiwizator profili.</li>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
Dzięki za korzystanie ze Szkolnego!<br>
|
||||
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2021</i>
|
||||
<i>© [Kuba Szczodrzyński](@kuba2k2) 2025</i>
|
||||
|