Compare commits

...

28 Commits

Author SHA1 Message Date
e389e6c073 [4.7-rc.2] Update build.gradle, signing and changelog. 2021-04-05 21:04:29 +02:00
cd6951dcbb [UI] Add highlighting user mentions in changelog. 2021-04-05 21:02:49 +02:00
02d60754b6 [UI] Fix changelog dialog link highlighting. 2021-04-05 20:38:51 +02:00
6884251646 [UI] Fix English translation typo. 2021-04-05 20:12:38 +02:00
582e2059d8 [App] Move buildTimestamp to manifest to improve build performance. 2021-04-05 20:00:38 +02:00
ea2974bfae [App] Improve unofficial build type info on debug. 2021-04-05 19:46:22 +02:00
b8ff649c96 [UI] Move privacy policy dialog to login chooser. 2021-04-05 19:45:57 +02:00
8661ecdafb Finish English translation (#12)
* [Feature] Espionage 0.5 speed

* [Languages] Start translating app to English

* [Languages] More English translations

* [Languages] Finish English translation

* Fix bugs in typing

* Revert "[Feature] Espionage 0.5 speed"

This reverts commit b925d3137a.

* Remove Espionage [*]

* Another typo

* Fix things that were described in review

* Fix typo

* Hour -> Time

* Update line breaks in strings file.

* Remove unneeded whitespace.

* Update English translations.

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2021-04-05 19:07:25 +02:00
fe8cbc061d Merge pull request #14 from szkolny-eu/feature/readme-update
README update
2021-04-05 19:06:41 +02:00
b4459e1fd4 [Git] Add workflow badges to README. 2021-04-05 13:08:21 +02:00
fd6553871f [Git] Add banner image to README. 2021-04-05 13:00:30 +02:00
a4ca44e1ce [Git] Add README banner image. 2021-04-05 12:58:54 +02:00
e124c429d1 [Actions] Update nightly build schedule. 2021-04-05 11:25:22 +02:00
e9a2dae1e4 [Gradle] Fix moving artifacts to release folder, again. 2021-04-05 10:56:13 +02:00
8b0f3490e3 [UI/Settings] Fix hiding hiding sticks from old without devMode. 2021-04-04 22:41:20 +02:00
131606a6cf Merge pull request #13 from szkolny-eu/feature/gh-actions
Add GitHub Actions
2021-04-04 22:36:55 +02:00
cacafa205e Merge pull request #9 from Zaptyp/patch-1
Correction of spelling and punctuation errors
2021-04-04 22:36:42 +02:00
9c620de1e7 [Actions] Add nightly build workflow. 2021-04-04 21:43:00 +02:00
3e98fb967b [Actions] Add Google Play build workflow. 2021-04-04 21:42:08 +02:00
8db81478f3 [Actions] Add release build workflow. 2021-04-04 21:41:55 +02:00
8f9861bac6 [Actions] Add workflow utilities scripts. 2021-04-04 21:41:36 +02:00
5b35e3500e [Gradle] Fix moving app bundles to release folder. 2021-04-04 20:37:02 +02:00
fc4c297bef [App] Add more info to build details dialog. 2021-04-03 22:22:18 +02:00
e7cb699bcf [App] Fix unofficial build notice formatting. 2021-04-03 15:58:59 +02:00
5301b4efad [Gradle] Add moving app bundles to release folder. 2021-04-03 15:35:00 +02:00
bf595dd09c [App] Fix detecting correct remote repository name. 2021-04-03 15:13:10 +02:00
cb4b168b2a Update README.md 2021-04-02 10:12:13 +02:00
b2fcbb8289 Correction of spelling and punctuation errors
Correction of spelling and punctuation errors and improved text appearance.
2021-04-02 06:55:27 +02:00
29 changed files with 1394 additions and 67 deletions

BIN
.github/readme-banner.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

2
.github/utils/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
__pycache__/

57
.github/utils/_get_password.py vendored Normal file
View File

@ -0,0 +1,57 @@
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",
)
print(f"Generating passwords for version {version_name} ({version_code})")
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])

142
.github/utils/_utils.py vendored Normal file
View File

@ -0,0 +1,142 @@
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)

69
.github/utils/bump_nightly.py vendored Normal file
View File

@ -0,0 +1,69 @@
import json
import os
import re
import sys
from datetime import datetime, timedelta
import requests
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)
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=1&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("::set-output name=hasNewChanges::false")
exit(0)
print("::set-output name=hasNewChanges::true")
project_dir = get_project_dir()
(version_code, version_name) = read_gradle_version(project_dir)
version_name = version_name.split("+")[0]
date = datetime.now()
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("::set-output name=appVersionName::" + version_name)
print("::set-output name=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
View 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")

59
.github/utils/extract_changelogs.py vendored Normal file
View File

@ -0,0 +1,59 @@
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("::set-output name=appVersionName::" + version_name)
print("::set-output name=appVersionCode::" + str(version_code))
dir = f"{project_dir}/app/release/whatsnew-{version_name}/"
os.makedirs(dir, exist_ok=True)
print("::set-output name=changelogDir::" + dir)
(title, changelog) = get_changelog(project_dir, format="plain")
with open(dir + "whatsnew-pl-PL", "w", encoding="utf-8") as f:
f.write(changelog)
print("::set-output name=changelogPlainFile::" + dir + "whatsnew-pl-PL")
with open(dir + "whatsnew-titled.txt", "w", encoding="utf-8") as f:
f.write(title)
f.write("\n")
f.write(changelog)
print("::set-output name=changelogPlainTitledFile::" + dir + "whatsnew-titled.txt")
print("::set-output name=changelogTitle::" + title)
(_, changelog) = get_changelog(project_dir, format="markdown")
with open(dir + "whatsnew.md", "w", encoding="utf-8") as f:
f.write(changelog)
print("::set-output name=changelogMarkdownFile::" + dir + "whatsnew.md")
(_, changelog) = get_changelog(project_dir, format="html")
with open(dir + "whatsnew.html", "w", encoding="utf-8") as f:
f.write(changelog)
print("::set-output name=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("::set-output name=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("::set-output name=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("::set-output name=commitLogHtmlFile::" + dir + "commit_log.html")

26
.github/utils/rename_artifacts.py vendored Normal file
View 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(os.getenv("GITHUB_WORKSPACE") + "/", "")
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("::set-output name=signedReleaseFile::" + file)
print("::set-output name=signedReleaseFileRelative::" + file_relative)

122
.github/utils/save_version.py vendored Normal file
View File

@ -0,0 +1,122 @@
import glob
import os
import sys
from datetime import datetime
from time import time
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).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
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)

84
.github/utils/sign.py vendored Normal file
View File

@ -0,0 +1,84 @@
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{} }};"
print(f"Writing passwords for version {version_name} ({version_code})")
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("::set-output name=appVersionName::" + version_name)
print("::set-output name=appVersionCode::" + str(version_code))
sign(
project_dir,
version_name,
version_code,
password,
iv,
commit="commit" in sys.argv,
)

118
.github/utils/webhook_discord.py vendored Normal file
View File

@ -0,0 +1,118 @@
import os
import sys
from datetime import datetime
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,
apk_server_release: str,
apk_server_nightly: 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
apk_name = os.path.basename(apk_file)
if build_type in ["nightly", "daily"]:
download_url = apk_server_nightly + apk_name
else:
download_url = apk_server_release + apk_name
if testing:
build_date = int(os.stat(apk_file).st_mtime)
if build_date:
build_date = datetime.fromtimestamp(build_date).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(changelog, download_url)
requests.post(url=webhook_release, json=webhook)
def get_webhook_release(changelog: str, download_url: str):
(title, content) = changelog
return {"content": f"__**{title}**__\n{content}\n{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")
APK_SERVER_RELEASE = os.getenv("APK_SERVER_RELEASE")
APK_SERVER_NIGHTLY = os.getenv("APK_SERVER_NIGHTLY")
WEBHOOK_RELEASE = os.getenv("WEBHOOK_RELEASE")
WEBHOOK_TESTING = os.getenv("WEBHOOK_TESTING")
post_webhook(
project_dir,
APK_FILE,
APK_SERVER_RELEASE,
APK_SERVER_NIGHTLY,
WEBHOOK_RELEASE,
WEBHOOK_TESTING,
)

151
.github/workflows/build-nightly-apk.yml vendored Normal file
View File

@ -0,0 +1,151 @@
name: Nightly build
on:
schedule:
# 23:30 UTC, 0:30 or 1:30 CET/CEST
- cron: "30 23 * * *"
workflow_dispatch:
jobs:
prepare:
name: Prepare build environment
runs-on: self-hosted
outputs:
hasNewChanges: ${{ steps.nightly.outputs.hasNewChanges }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0
clean: false
- name: Set executable permissions to gradlew
run: chmod +x ./gradlew
- name: Setup Python
uses: actions/setup-python@v2
- name: Install packages
uses: BSFishy/pip-action@v1
with:
packages: |
python-dotenv
pycryptodome
mysql-connector-python
requests
- name: Bump nightly version
id: nightly
run: python $GITHUB_WORKSPACE/.github/utils/bump_nightly.py $GITHUB_WORKSPACE
- name: Write signing passwords
if: steps.nightly.outputs.hasNewChanges
env:
DB_HOST: ${{ secrets.DB_HOST }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASS: ${{ secrets.DB_PASS }}
DB_NAME: ${{ secrets.DB_NAME }}
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
build:
name: Build APK
runs-on: self-hosted
needs:
- prepare
if: needs.prepare.outputs.hasNewChanges
outputs:
androidHome: ${{ env.ANDROID_HOME }}
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
steps:
- name: Setup JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Clean build artifacts
run: |
rm -rf app/release/*
rm -rf app/build/outputs/apk/*
rm -rf app/build/outputs/bundle/*
- name: Assemble official release with Gradle
run: ./gradlew assembleOfficialRelease
sign:
name: Sign APK
runs-on: self-hosted
needs:
- build
outputs:
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
steps:
- name: Sign build artifacts
id: sign_app
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: app/release
signingKeyBase64: ${{ secrets.KEY_STORE }}
alias: ${{ secrets.KEY_ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
env:
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
BUILD_TOOLS_VERSION: "30.0.2"
- name: Rename signed artifacts
id: artifacts
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
publish:
name: Publish APK
runs-on: self-hosted
needs:
- sign
steps:
- name: Setup Python
uses: actions/setup-python@v2
- name: Extract changelogs
id: changelog
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
- name: Upload APK to SFTP
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: ${{ needs.sign.outputs.signedReleaseFileRelative }}
TARGET: ${{ secrets.SSH_PATH_NIGHTLY }}
- name: Save version metadata
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
- name: Distribute to App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
token: ${{ secrets.FIREBASE_TOKEN }}
groups: ${{ secrets.FIREBASE_GROUPS_NIGHTLY }}
file: ${{ needs.sign.outputs.signedReleaseFile }}
releaseNotesFile: ${{ steps.changelog.outputs.commitLogPlainFile }}
- name: Post Discord webhook
env:
APK_FILE: ${{ needs.sign.outputs.signedReleaseFile }}
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE
- name: Upload workflow artifact
uses: actions/upload-artifact@v2
if: true
with:
name: ${{ steps.changelog.outputs.appVersionName }}
path: |
app/release/whatsnew*/
app/release/*.apk
app/release/*.aab
app/release/*.json
app/release/*.txt

View File

@ -0,0 +1,129 @@
name: Release build - Google Play [AAB]
on:
push:
branches:
- "master"
jobs:
prepare:
name: Prepare build environment
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0
clean: false
- name: Set executable permissions to gradlew
run: chmod +x ./gradlew
- name: Setup Python
uses: actions/setup-python@v2
- name: Install packages
uses: BSFishy/pip-action@v1
with:
packages: |
python-dotenv
pycryptodome
mysql-connector-python
requests
- name: Write signing passwords
env:
DB_HOST: ${{ secrets.DB_HOST }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASS: ${{ secrets.DB_PASS }}
DB_NAME: ${{ secrets.DB_NAME }}
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
build:
name: Build App Bundle
runs-on: self-hosted
needs:
- prepare
outputs:
androidHome: ${{ env.ANDROID_HOME }}
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
steps:
- name: Setup JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Clean build artifacts
run: |
rm -rf app/release/*
rm -rf app/build/outputs/apk/*
rm -rf app/build/outputs/bundle/*
- name: Bundle play release with Gradle
run: ./gradlew bundlePlayRelease
sign:
name: Sign App Bundle
runs-on: self-hosted
needs:
- build
outputs:
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
steps:
- name: Sign build artifacts
id: sign_app
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: app/release
signingKeyBase64: ${{ secrets.KEY_STORE }}
alias: ${{ secrets.KEY_ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
env:
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
BUILD_TOOLS_VERSION: "30.0.2"
- name: Rename signed artifacts
id: artifacts
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
publish:
name: Publish App Bundle
runs-on: self-hosted
needs:
- sign
steps:
- name: Setup Python
uses: actions/setup-python@v2
- name: Extract changelogs
id: changelog
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
- name: Save version metadata
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
- name: Publish AAB to Google Play
uses: r0adkll/upload-google-play@v1
if: ${{ endsWith(needs.sign.outputs.signedReleaseFile, '.aab') }}
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
packageName: pl.szczodrzynski.edziennik
releaseFile: ${{ needs.sign.outputs.signedReleaseFile }}
releaseName: ${{ steps.changelog.outputs.appVersionName }}
track: ${{ secrets.PLAY_RELEASE_TRACK }}
userFraction: 1.0
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
- name: Upload workflow artifact
uses: actions/upload-artifact@v2
if: true
with:
name: ${{ steps.changelog.outputs.appVersionName }}
path: |
app/release/whatsnew*/
app/release/*.apk
app/release/*.aab
app/release/*.json
app/release/*.txt

151
.github/workflows/build-release-apk.yml vendored Normal file
View File

@ -0,0 +1,151 @@
name: Release build - official
on:
push:
tags:
- "*"
jobs:
prepare:
name: Prepare build environment
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0
clean: false
- name: Set executable permissions to gradlew
run: chmod +x ./gradlew
- name: Setup Python
uses: actions/setup-python@v2
- name: Install packages
uses: BSFishy/pip-action@v1
with:
packages: |
python-dotenv
pycryptodome
mysql-connector-python
requests
- name: Write signing passwords
env:
DB_HOST: ${{ secrets.DB_HOST }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASS: ${{ secrets.DB_PASS }}
DB_NAME: ${{ secrets.DB_NAME }}
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
build:
name: Build APK
runs-on: self-hosted
needs:
- prepare
outputs:
androidHome: ${{ env.ANDROID_HOME }}
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
steps:
- name: Setup JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Clean build artifacts
run: |
rm -rf app/release/*
rm -rf app/build/outputs/apk/*
rm -rf app/build/outputs/bundle/*
- name: Assemble official release with Gradle
run: ./gradlew assembleOfficialRelease
sign:
name: Sign APK
runs-on: self-hosted
needs:
- build
outputs:
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
steps:
- name: Sign build artifacts
id: sign_app
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: app/release
signingKeyBase64: ${{ secrets.KEY_STORE }}
alias: ${{ secrets.KEY_ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
env:
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
BUILD_TOOLS_VERSION: "30.0.2"
- name: Rename signed artifacts
id: artifacts
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
publish:
name: Publish APK
runs-on: self-hosted
needs:
- sign
steps:
- name: Setup Python
uses: actions/setup-python@v2
- name: Extract changelogs
id: changelog
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
- name: Upload APK to SFTP
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: ${{ needs.sign.outputs.signedReleaseFileRelative }}
TARGET: ${{ secrets.SSH_PATH_RELEASE }}
- name: Save version metadata
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
- name: Distribute to App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
token: ${{ secrets.FIREBASE_TOKEN }}
groups: ${{ secrets.FIREBASE_GROUPS_RELEASE }}
file: ${{ needs.sign.outputs.signedReleaseFile }}
releaseNotesFile: ${{ steps.changelog.outputs.changelogPlainTitledFile }}
- name: Release on GitHub
uses: softprops/action-gh-release@v1
with:
name: ${{ steps.changelog.outputs.changelogTitle }}
body_path: ${{ steps.changelog.outputs.changelogMarkdownFile }}
files: ${{ needs.sign.outputs.signedReleaseFile }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Post Discord webhook
env:
APK_FILE: ${{ needs.sign.outputs.signedReleaseFile }}
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE
- name: Upload workflow artifact
uses: actions/upload-artifact@v2
if: true
with:
name: ${{ steps.changelog.outputs.appVersionName }}
path: |
app/release/whatsnew*/
app/release/*.apk
app/release/*.aab
app/release/*.json
app/release/*.txt

View File

@ -1,9 +1,7 @@
# Szkolny.eu
Nieoficjalna aplikacja do obsługi najpopularniejszych dzienników elektronicznych w Polsce.
<div align="center">
![Readme Banner](.github/readme-banner.png)
[![Discord](https://img.shields.io/discord/619178050562686988?color=%237289DA&logo=discord&logoColor=white&style=for-the-badge)](https://szkolny.eu/discord)
[![Oficjalna strona](https://img.shields.io/badge/-website-orange?style=for-the-badge&logo=internet-explorer&logoColor=white)](https://szkolny.eu/)
[![Facebook Fanpage](https://img.shields.io/badge/-facebook-blue?style=for-the-badge&logo=facebook&logoColor=white)](https://szkolny.eu/facebook)
@ -12,11 +10,15 @@ Nieoficjalna aplikacja do obsługi najpopularniejszych dzienników elektroniczny
[![Najnowsza wersja](https://img.shields.io/github/v/release/szkolny-eu/szkolny-android?color=%2344CC11&include_prereleases&logo=github&logoColor=white&style=for-the-badge)](https://github.com/szkolny-eu/szkolny-android/releases/latest)
![Licencja](https://img.shields.io/github/license/szkolny-eu/szkolny-android?color=blue&logo=github&logoColor=white&style=for-the-badge)
[![Release build](https://img.shields.io/github/workflow/status/szkolny-eu/szkolny-android/Release%20build%20-%20official?label=Release&logo=github-actions&logoColor=white&style=for-the-badge)](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-release-apk.yml)
[![Play build](https://img.shields.io/github/workflow/status/szkolny-eu/szkolny-android/Release%20build%20-%20Google%20Play%20%5BAAB%5D?label=Play&logo=google-play&logoColor=white&style=for-the-badge)](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-release-aab-play.yml)
[![Nightly build](https://img.shields.io/github/workflow/status/szkolny-eu/szkolny-android/Nightly%20build?label=Nightly&logo=github-actions&logoColor=white&style=for-the-badge)](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-nightly-apk.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&reg; 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&reg; 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.**

View File

@ -18,8 +18,10 @@ 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
@ -98,7 +100,10 @@ tasks.whenTaskAdded { task ->
if (flavor != "") {
tasks.create(renameTaskName, Copy) {
from file("${projectDir}/${flavor}/release/"), file("${buildDir}/outputs/mapping/${flavor}Release/")
from file("${projectDir}/${flavor}/release/"),
file("${buildDir}/outputs/mapping/${flavor}Release/"),
file("${buildDir}/outputs/apk/${flavor}/release/"),
file("${buildDir}/outputs/bundle/${flavor}Release/")
include "*.aab", "*.apk", "mapping.txt", "output-metadata.json"
destinationDir file("${projectDir}/release/")
rename ".+?\\.(.+)", "Edziennik_${android.defaultConfig.versionName}_${flavor}." + '$1'

View File

@ -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(", ") + ")"
}

View File

@ -29,6 +29,8 @@
android:usesCleartextTraffic="true"
tools:ignore="UnusedAttribute">
<meta-data android:name="buildTimestamp" android:value="${buildTimestamp}" />
<!-- __ __ _ _ _ _ _
| \/ | (_) /\ | | (_) (_) |
| \ / | __ _ _ _ __ / \ ___| |_ ___ ___| |_ _ _

View File

@ -1,14 +1,15 @@
<h3>Wersja 4.7-rc.1, 2021-04-01</h3>
<h3>Wersja 4.7-rc.2, 2021-04-05</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><u>Szkolny.eu jest teraz open source!</u> Zapraszamy na stronę <a href="https://szkolny.eu/">https://szkolny.eu/</a> 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>Zaktualizowano tłumaczenie na język angielski. @MarcinK50</li>
<li>Dodano ekran informacji o kompilacji w Ustawieniach.</li>
<li>Zaktualizowano ekran licencji open source.</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>Zoptymalizowano wielkość aplikacji.</li>
</ul>
<br>
<br>
Dzięki za korzystanie ze Szkolnego!<br>
<i>&copy; Kuba Szczodrzyński, Kacper Ziubryniewicz 2021</i>
<i>&copy; [Kuba Szczodrzyński](@kuba2k2), [Kacper Ziubryniewicz](@kapi2289) 2021</i>

View File

@ -9,7 +9,7 @@
/*secret password - removed for source code publication*/
static toys AES_IV[16] = {
0xdd, 0x0a, 0x72, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0x25, 0x68, 0xd4, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);

View File

@ -46,6 +46,6 @@ object Signing {
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
return "$param1.MTIzNDU2Nzg5MDy+5jm3L0===.$param2".sha256()
return "$param1.MTIzNDU2Nzg5MD+7y77uUm===.$param2".sha256()
}
}

View File

@ -17,6 +17,7 @@ import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.dp
import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod
import kotlin.coroutines.CoroutineContext
class ChangelogDialog(
@ -43,9 +44,14 @@ class ChangelogDialog(
val textView = TextView(activity)
textView.setPadding(24.dp, 24.dp, 24.dp, 0)
val text = app.assets.open("pl-changelog.html").bufferedReader().use {
var text = app.assets.open("pl-changelog.html").bufferedReader().use {
it.readText()
}
val commitsUrlPrefix = "https://github.com/szkolny-eu/szkolny-android/commits?author="
text = text.replace("""\[(.+?)]\(@([A-z0-9-]+)\)""".toRegex(), "<a href=\"$commitsUrlPrefix$2\">$1</a>")
text = text.replace("""\s@([A-z0-9-]+)""".toRegex(), " <a href=\"$commitsUrlPrefix$1\">@$1</a>")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.text = Html.fromHtml(text)
}
@ -53,6 +59,8 @@ class ChangelogDialog(
textView.text = Html.fromHtml(text.replace("<li>", "<br><li> - "))
}
textView.movementMethod = BetterLinkMovementMethod.getInstance()
val scrollView = ScrollView(activity)
scrollView.addView(textView)
@ -67,4 +75,4 @@ class ChangelogDialog(
}
.show()
}}
}
}

View File

@ -10,12 +10,14 @@ import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@ -29,6 +31,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailability
import pl.szczodrzynski.edziennik.databinding.LoginChooserFragmentBinding
import pl.szczodrzynski.edziennik.ui.dialogs.RegisterUnavailableDialog
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackActivity
import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
import kotlin.coroutines.CoroutineContext
@ -203,6 +206,23 @@ class LoginChooserFragment : Fragment(), CoroutineScope {
return
}
if (!app.config.privacyPolicyAccepted) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.privacy_policy)
.setMessage(Html.fromHtml(activity.getString(R.string.privacy_policy_dialog_html)))
.setPositiveButton(R.string.i_agree) { _, _ ->
app.config.privacyPolicyAccepted = true
onLoginModeClicked(loginType, loginMode)
}
.setNegativeButton(R.string.i_disagree, null)
.show()
.also { dialog ->
dialog.findViewById<TextView>(android.R.id.message)?.movementMethod =
BetterLinkMovementMethod.getInstance()
}
return
}
launch {
if (!checkAvailability(loginType.loginType))
return@launch

View File

@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.ui.modules.login
import android.os.Bundle
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -75,19 +74,6 @@ class LoginSummaryFragment : Fragment(), CoroutineScope {
}
b.finishButton.onClick {
if (!app.config.privacyPolicyAccepted) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.privacy_policy)
.setMessage(Html.fromHtml("Korzystając z aplikacji potwierdzasz <a href=\"http://szkolny.eu/privacy-policy\">przeczytanie Polityki prywatności</a> i akceptujesz jej postanowienia."))
.setPositiveButton(R.string.i_agree) { _, _ ->
app.config.privacyPolicyAccepted = true
b.finishButton.performClick()
}
.setNegativeButton(R.string.i_disagree, null)
.show()
return@onClick
}
val args = Bundle(
"registrationAllowed" to b.registerMeSwitch.isChecked
)

View File

@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.ui.modules.settings.cards
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import eu.szkolny.font.SzkolnyFont
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.after
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
@ -141,12 +142,15 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) {
else
null,
util.createPropertyItem(
text = R.string.settings_register_hide_sticks_from_old,
icon = CommunityMaterial.Icon3.cmd_numeric_1_box_outline,
value = configProfile.grades.hideSticksFromOld
) { _, it ->
configProfile.grades.hideSticksFromOld = it
}
if (App.devMode)
util.createPropertyItem(
text = R.string.settings_register_hide_sticks_from_old,
icon = CommunityMaterial.Icon3.cmd_numeric_1_box_outline,
value = configProfile.grades.hideSticksFromOld
) { _, it ->
configProfile.grades.hideSticksFromOld = it
}
else
null
)
}

View File

@ -4,6 +4,7 @@
package pl.szczodrzynski.edziennik.utils.managers
import android.content.pm.PackageManager
import android.text.TextUtils
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
@ -26,12 +27,18 @@ class BuildManager(val app: App) : CoroutineScope {
val buildFlavor = BuildConfig.FLAVOR
val buildType = BuildConfig.BUILD_TYPE
val buildTimestamp = BuildConfig.BUILD_TIMESTAMP
val isRelease = !BuildConfig.DEBUG
val isDebug = BuildConfig.DEBUG
val isNightly = BuildConfig.VERSION_NAME.contains("nightly")
val isDaily = BuildConfig.VERSION_NAME.contains("daily")
val buildTimestamp: Long
get() {
val info = app.packageManager.getApplicationInfo(app.packageName, PackageManager.GET_META_DATA)
val metadata = info.metaData
return metadata?.getFloat("buildTimestamp")?.toLong() ?: 0
}
val gitHash = BuildConfig.GIT_INFO["hash"]
val gitVersion = BuildConfig.GIT_INFO["version"]
val gitBranch = BuildConfig.GIT_INFO["branch"]
@ -56,9 +63,9 @@ class BuildManager(val app: App) : CoroutineScope {
}
val versionBadge = when {
isOfficial && isNightly ->
isSigned && isNightly ->
"Nightly\n" + BuildConfig.VERSION_NAME.substringAfterLast('.')
isOfficial && isDaily ->
isSigned && isDaily ->
"Daily\n" + BuildConfig.VERSION_NAME.substringAfterLast('.')
isDebug ->
"Debug\n" + BuildConfig.VERSION_BASE
@ -78,10 +85,22 @@ class BuildManager(val app: App) : CoroutineScope {
val fields = mapOf(
R.string.build_version to BuildConfig.VERSION_BASE,
R.string.build_official to if (isOfficial)
yes.asColoredSpannable(mtrlGreen)
else
no.asColoredSpannable(mtrlRed),
R.string.build_official to when {
isOfficial -> yes.asColoredSpannable(mtrlGreen)
isSigned -> TextUtils.concat(
yes.asColoredSpannable(mtrlYellow),
when {
isNightly -> " (nightly build)"
isDaily -> " (daily build)"
else -> no.asColoredSpannable(mtrlYellow)
}
)
isDebug -> no
else -> TextUtils.concat(
no.asColoredSpannable(mtrlRed),
if (gitAuthor.isNotNullNorBlank()) " ($gitAuthor)" else ""
)
},
R.string.build_platform to when {
isPlayRelease -> activity.getString(R.string.build_platform_play)
isApkRelease -> activity.getString(R.string.build_platform_apk)
@ -229,8 +248,10 @@ class BuildManager(val app: App) : CoroutineScope {
val validation = Signing.appCertificate + gitHash + gitRemotes?.join(";")
// app already validated
if (app.config.validation == validation.md5())
if (app.config.validation?.substringBefore(":") == validation.md5()){
gitAuthor = app.config.validation?.substringAfter(":")
return@launch
}
val dialog = MaterialAlertDialogBuilder(activity)
.setTitle(R.string.please_wait)
@ -251,7 +272,7 @@ class BuildManager(val app: App) : CoroutineScope {
}
// release, unofficial, published build
app.config.validation = validation.md5()
app.config.validation = validation.md5() + ":" + gitAuthor
invalidateBuild(activity, dialog, InvalidBuildReason.VALID)
}
}

View File

@ -1235,5 +1235,135 @@
<string name="permissions_attachment">In order to download the file, you have to grant file storage permission for the application.\n\nClick OK to grant the permission.</string>
<string name="permissions_denied">You denied the required permissions for the application.\n\nIn order to grant the permission, open the Permissions screen for Szkolny.eu in phone settings.\n\nClick OK to open app settings now.</string>
<string name="permissions_required">Required permissions</string>
<string name="settings_register_hide_sticks_from_old">Your mother won\'t see your F grades</string>
<string name="settings_register_hide_sticks_from_old">Hide sticks from old</string>
<string name="build_official">Official build</string>
<string name="build_platform_play">Google Play</string>
<string name="login_chooser_testing_title">Testing version</string>
<string name="login_chooser_mode_recommended">{cmd-information-outline} Recommended</string>
<string name="login_chooser_mode_dev_only">{cmd-android-studio} Developer version</string>
<string name="login_chooser_mode_testing">{cmd-alert-circle-outline} Testing version</string>
<string name="eggs">\???</string>
<string name="see_also">See also</string>
<string name="settings_about_github_text">Source code</string>
<string name="build_branch">Git branch</string>
<string name="build_platform_apk">.APK</string>
<string name="build_platform_unofficial">Unofficial (.APK)</string>
<string name="build_commit">Commit hash</string>
<string name="build_dirty">Unsaved changes</string>
<string name="build_tag">Last tag</string>
<string name="build_rev_count">Commits since last tag</string>
<string name="build_remote">Remote repository</string>
<string name="build_details">Build details</string>
<string name="build_dialog_open_repo">Check code</string>
<string name="profile_config_name_hint">Profile name</string>
<string name="profile_config_logout">Logout</string>
<string name="profile_config_sync_enabled">Synchronize this profile</string>
<string name="home_availability_update">Update</string>
<string name="update_available_later">Not now</string>
<string name="update_available_button">Update</string>
<string name="login_type_edudziennik">EduDziennik</string>
<string name="login_form_title_format">Log in - %s</string>
<string name="attendance_details_date">Date</string>
<string name="attendance_details_teacher">Teacher</string>
<string name="attendance_tab_days">By days</string>
<string name="attendance_tab_list">List</string>
<string name="attendance_lesson_number_format">lesson %d</string>
<string name="attendance_tab_types">By type</string>
<string name="settings_add_student_text">Add new student</string>
<string name="attendance_details_lesson_topic">Lesson subject</string>
<string name="register_unavailable_read_more">Read more</string>
<string name="build_version">App version</string>
<string name="settings_about_version_details_text">Version details</string>
<string name="build_date">Build date</string>
<string name="error_no_api_access">No API access</string>
<string name="attendance_details_time">Time</string>
<string name="settings_about_github_subtext">Help with app development on GitHub</string>
<string name="build_platform">Distribution</string>
<string name="build_validate_progress">Build verification in progress...</string>
<string name="attendance_tab_months">By months</string>
<string name="attendance_tab_summary">Summary</string>
<string name="attendance_details_type">Type</string>
<string name="home_availability_info">See more</string>
<string name="home_availability_title">Update available</string>
<string name="settings_about_version_details_subtext">Build details</string>
<string name="home_availability_text">Update app to the latest version - %s.</string>
<string name="update_available_title">App update available</string>
<string name="home_archive_close">Close archive</string>
<string name="home_archive_title">Archived profile</string>
<string name="profile_archived_title">Profile is archived</string>
<string name="profile_year_not_started_title">Holiday ;)</string>
<string name="profile_archiving_title">The end of the school year</string>
<string name="login_podlasie_logout_devices">Logout from other devices</string>
<string name="event_manual_no_profile">Student profile not found.</string>
<string name="settings_about_homepage_text">Go to application website</string>
<string name="settings_about_homepage_subtext">Get help or support authors</string>
<string name="build_invalid_title">Information about application version</string>
<string name="home_archive_close_no_target_title">No current profile</string>
<string name="login_platform_list_loading">Loading e-registers list...</string>
<string name="login_mode_podlasie_api">Log in using token</string>
<string name="login_mode_podlasie_api_guide">Provide mobile app token.</string>
<string name="attendance_config_title">Attendance configuration</string>
<string name="attendance_config_use_symbols">Show symbols and colors from e-register config</string>
<string name="attendance_empty_text">There are no absences here.</string>
<string name="grades_empty_text">There are no grades in this semester</string>
<string name="menu_attendance_config">Attendance settings</string>
<string name="login_chooser_title">What is your e-register at school?</string>
<string name="login_mode_librus_synergia">Log in using login and password</string>
<string name="login_mode_librus_synergia_hint">Use a login in form of \"9874123u\"</string>
<string name="login_mode_vulcan_api">Use token, symbol and PIN code</string>
<string name="login_mode_vulcan_api_hint">Register device on journal VULCAN® page</string>
<string name="login_mode_vulcan_web">Use e-mail/username and password</string>
<string name="edziennik_progress_login_podlasie_api">Logging in to PPE...</string>
<string name="login_type_podlasie">Podlaska Platforma Edukacyjna</string>
<string name="login_mode_edudziennik_web">Log in using e-mail and password</string>
<string name="edziennik_progress_login_vulcan_web_main">Logging in to VULCAN® register...</string>
<string name="login_mode_librus_jst">Login via VULCAN® platform</string>
<string name="login_mode_librus_email">Log in using e-mail</string>
<string name="attendance_details_id">Attendance ID</string>
<string name="login_mode_mobidziennik_web">Log in with the server name, login and password</string>
<string name="login_mode_vulcan_web_hint">Log in with the data that you provide on VULCAN® e-register website</string>
<string name="login_mode_mobidziennik_web_hint">Provide data, that you use on e-register website</string>
<string name="attendance_details_type_id">Base type ID</string>
<string name="attendance_details_is_counted">Counted to the stats?</string>
<string name="login_chooser_subtitle">Choose which e-register your school uses. If you have several accounts in different e-registers, you will be able to add them later.</string>
<string name="login_mode_librus_email_hint">You must have a LIBRUS® Rodzina account</string>
<string name="login_mode_librus_jst_hint">Only Oświata w Radomiu and Innowacyjny Tarnobrzeg</string>
<string name="login_platform_list_title">How do you log into the e-register?</string>
<string name="attendance_config_group_consecutive_days">Group consecutive days on the list</string>
<string name="attendance_config_use_symbols_hint">Visible when the list is expanded</string>
<string name="attendance_config_show_presence_in_month">Display attendance in months view</string>
<string name="attendance_percentage_format">%.2f%%</string>
<string name="attendance_period_summary_format">Attendance during this period: %.2%%</string>
<string name="settings_add_student_subtext">Log in child/parent account in app</string>
<string name="login_mode_edudziennik_web_guide">Enter the e-mail address and password that you use to log in to the browser on the EduDziennik website.</string>
<string name="profile_year_not_started_format">Probably the school year for this student has not yet started (will start %s). Please try to sync later.</string>
<string name="profile_archiving_format">The school year ended on %s. Student data from the previous year will be moved to the archive for later review.</string>
<string name="login_copyright_notice">Trademarks featured in this application belong to their rightful owners and are used for informational purposes only.</string>
<string name="home_archive_text">You are viewing a student\'s data from the school year %d/%d.</string>
<string name="login_mode_edudziennik_web_hint">Use data, that you enter on the e-register website</string>
<string name="permissions_qr_scanner">To be able to scan the QR code, you need to grant access to the camera.\n\nClick OK to grant permissions.</string>
<string name="rate_snackbar_negative_message">It\'s a pity, the opinions of others help me develop the application.</string>
<string name="login_chooser_testing_text">The selected login method is still being tested and may not work properly. If you have problems with the app, please choose the recommended login method.</string>
<string name="update_available_fallback">You have an outdated version of the Szkolny.eu application. You need to update the app to continue to sync data.</string>
<string name="update_available_format">You are using an old version of the Szkolny.eu application (%s). To use the app and ensure the best performance, please upgrade to %s. Change log: %s</string>
<string name="profile_archived_text">You are viewing a student\'s data from the previous school year (%d /%d). Syncing and downloading of messages and some homework have been disabled. To open a student\'s profile for the current year, select Close Archive on the home page.</string>
<string name="login_mode_librus_jst_guide">Log in to LIBRUS® Synergia on your computer, select the Mobile Applications tab, then enter the received Token and PIN below.</string>
<string name="login_mode_librus_synergia_guide">Enter the login received from the school with which you log into LIBRUS® Synergia (purple form).\n\nIt is recommended to log in with the LIBRUS® Family account (using e-mail) in the previous step.</string>
<string name="login_mode_librus_email_guide">Log in with your LIBRUS® Rodzina account, which works in the official LIBRUS® application and on the website portal.librus.pl, in the blue form. \n\nIf you do not have a LIBRUS® Rodzina account, you can create one at https://portal.librus.pl/rodzina/register.</string>
<string name="login_platform_list_loading_timeout">If it takes too long, please check your internet connection and restart the application.</string>
<string name="login_platform_list_subtitle">Select which image corresponds to the one you see when logging in to your log website. If your school doesn\'t use any of these city platforms, choose the first option.</string>
<string name="build_invalid_remote_no_commit">You have an application build with unpublished changes. The build is in the repository:\n%1$s (%2$s)\nwhich is private or does not contain the latest changes.\n\nFor security reasons and compliance with the license, the use of the application has been blocked.</string>
<string name="login_mode_vulcan_api_guide">Log in to the VULCAN® log on your computer, select the Mobile Access tab, click the Register mobile device button. Enter the received Token, Symbol and PIN in the fields below.</string>
<string name="login_mode_vulcan_web_guide">Enter the data that you log in to the VULCAN® log website or the city platform.</string>
<string name="build_invalid_official_unsigned">You cannot modify this type of compilation of the Szkolny.eu application.\n\nTo make your own changes, please use the source code available on GitHub and see the README and license information.\n\nhttps://szkolny.eu/github/android</string>
<string name="build_invalid_unstaged_changes">This build contains changes not committed to any revision. Save and publish all changes before \"release\".\n\nFor security reasons and for compliance with the license, the use of the application has been blocked.</string>
<string name="build_invalid_debug">You are using a \"debug\" build. This information will only be displayed once for the current device.</string>
<string name="build_valid_unofficial">You are using an unofficial compilation of the Szkolny.eu application. We recommend that you use only the official versions of the application.\n\nLast changes in this version were made by:\n%3$s\nin the repository:\n%1$s (%2$s).\n\nThis window will not reappear.</string>
<string name="build_invalid_no_commit_hash">The hash of the current commit was not found. Check Gradle configuration.</string>
<string name="home_archive_close_no_target_text">Child %s does not have a profile on this account in the current school year. Probably this profile has been deleted or the student no longer attends this class.\n\nTo go to the current profile, select a student from the list or log in to their account with the Add student button.</string>
<string name="build_invalid_no_remote_repo">A reference to a remote repository was not found. Make sure you are using the official repository fork and verify your Gradle configuration.</string>
<string name="login_mode_mobidziennik_web_guide">"Enter the data you use to log in to the MobiDziennik website. As the server address, you can enter the address of the website where you have MobiDziennik. "</string>
<string name="permissions_generate_timetable">In order to be able to save the generated timetable, you must grant access rights to the device\'s memory.\n\nClick OK to grant permissions.</string>
<string name="login_summary_account_child">(Child)</string>
<string name="login_summary_account_parent">(Parent)</string>
</resources>

View File

@ -1346,10 +1346,6 @@
<string name="login_mode_vulcan_web_guide">Podaj dane, którymi logujesz się na stronie internetowej dziennika VULCAN® lub na miejskiej platformie.</string>
<string name="login_mode_mobidziennik_web_guide">Podaj dane, których używasz do logowania na stronie MobiDziennika. Jako adres serwera możesz wpisać adres strony internetowej, na której masz MobiDziennik.</string>
<string name="edziennik_progress_login_vulcan_web_main">Logowanie do dziennika VULCAN®...</string>
<string name="login_type_idziennik">iDziennik Progman / iUczniowie</string>
<string name="login_mode_idziennik_web">Zaloguj używając nazwy użytkownika i hasła</string>
<string name="login_mode_idziennik_web_hint">Podaj dane, których używasz na stronie internetowej e-dziennika</string>
<string name="login_mode_idziennik_web_guide">Użyj danych, które wpisujesz w formularz na stronie iDziennika. Jeśli nie pamiętasz hasła, wejdź na http://iuczniowie.progman.pl/ i kliknij przycisk \"Zapomniałem hasła\".</string>
<string name="login_type_edudziennik">EduDziennik</string>
<string name="login_mode_edudziennik_web">Zaloguj używając e-maila i hasła</string>
<string name="login_mode_edudziennik_web_hint">Użyj danych, które podajesz na stronie internetowej e-dziennika</string>
@ -1419,7 +1415,7 @@
<string name="build_invalid_official_unsigned">Nie możesz modyfikować tego rodzaju kompilacji aplikacji Szkolny.eu.\n\nAby wprowadzić własne zmiany, skorzystaj z kodu źródłowego dostępnego na GitHubie oraz zapoznaj się z README i informacją o licencji.\n\nhttps://szkolny.eu/github/android</string>
<string name="build_invalid_unstaged_changes">Ta kompilacja zawiera zmiany niezatwierdzone do żadnej rewizji. Zapisz oraz opublikuj wszystkie zmiany przed wydaniem wersji \"release\".\n\nDla bezpieczeństwa oraz ze względów zgodności z licencją, korzystanie z aplikacji zostało zablokowane.</string>
<string name="build_invalid_debug">Korzystasz z kompilacji typu \"debug\". Ta informacja zostanie wyświetlona tylko jeden raz dla aktualnego urządzenia.</string>
<string name="build_valid_unofficial">Korzystasz z nieoficjalnej kompilacji aplikacji Szkolny.eu. Zalecamy używanie wyłącznie oficjalnych wersji aplikacji.\n\nOstatnie zmiany w tej wersji zostały wprowadzone przez %3$s w repozytorium %2$s (%1$s).\n\nTo okno nie wyświetli się ponownie.</string>
<string name="build_valid_unofficial">Korzystasz z nieoficjalnej kompilacji aplikacji Szkolny.eu. Zalecamy używanie wyłącznie oficjalnych wersji aplikacji.\n\nOstatnie zmiany w tej wersji zostały wprowadzone przez:\n%3$s\nw repozytorium:\n%1$s (%2$s).\n\nTo okno nie wyświetli się ponownie.</string>
<string name="build_invalid_title">Informacja dotycząca wersji aplikacji</string>
<string name="settings_about_version_details_text">Szczegóły wersji</string>
<string name="settings_about_version_details_subtext">Informacje o kompilacji</string>
@ -1427,4 +1423,5 @@
<string name="error_no_api_access">Brak dostępu do API</string>
<string name="build_date">Data kompilacji</string>
<string name="permissions_generate_timetable">Aby móc zapisać wygenerowany plan lekcji musisz przyznać uprawnienia dostępu do pamięci urządzenia.\n\nKliknij OK, aby przyznać uprawnienia.</string>
<string name="privacy_policy_dialog_html"><![CDATA[Korzystając z aplikacji potwierdzasz <a href="https://szkolny.eu/privacy-policy">przeczytanie Polityki prywatności</a> i akceptujesz jej postanowienia.<br /><br />Autorzy aplikacji nie biorą odpowiedzialności za korzystanie z aplikacji Szkolny.eu.]]></string>
</resources>

View File

@ -5,8 +5,8 @@ buildscript {
kotlin_version = '1.4.31'
release = [
versionName: "4.7-rc.1",
versionCode: 4070010
versionName: "4.7-rc.2",
versionCode: 4070020
]
setup = [