Write Android build guide; fixed:

error when LANG=None
initial config have incorrect strength/energy
adjustments to docs and scripts
This commit is contained in:
NaitLee 2022-09-12 02:20:08 +08:00
parent cbfd904152
commit 70cdd84359
17 changed files with 516 additions and 100 deletions

5
.gitignore vendored
View File

@ -19,8 +19,11 @@ cat-printer*.zip
cat-printer-sha256-*.txt cat-printer-sha256-*.txt
# bleak, the bare pip package as a folder # bleak, the bare pip package as a folder
build-common/bleak build-common/bleak
# python embeddable package, with bleak_winrt inside # python embeddable package, historically with bleak_winrt inside
build-common/python-win32* build-common/python-win32*
build-common/python-w32*
# bleak_winrt is now outside python-w32
build-common/bleak_winrt
# dev config # dev config
config.json config.json
# dev backup # dev backup

View File

@ -3,73 +3,81 @@
Thank you for looking into this project. Thank you for looking into this project.
Let's keep short & be positive: Lets keep short & be positive:
## Communication ## Communication
1. Use Issue for a potential bug and Discussion for feature request. 1. Use Issue for a potential bug and Discussion for feature request.
But do whichever you feel better. This is just a hint. But do whichever you feel better. This is just a hint.
2. Consider you're interacting with the whole world. Use English. 2. Consider youre interacting with the world. Use English.
But you may also use another if you're confident enough that someone in community could understand it & help you. But you may also use another if youre confident enough that someone in community could understand it & help you.
## Sharing ## Sharing
Let's just call it "sharing". You can of course share your experience of this project with your friends, online or offline. Lets just call it “sharing”. You can of course share your experience of this project with your friends, online or offline.
This is also one step toward Software Freedom. This is also one step toward Software Freedom.
But note that, if necessary, disclaim that you have no relationship with any of the printer vendors. Neither the author(s) here. But note that, if necessary, disclaim that you have no relationship with any of the printer vendors. Neither the author(s) here.
Also for avoiding potential hassle, don't mention the "original" or "official" app(s). Also for avoiding potential hassle, dont mention the “original” or “official” app(s).
## Translating ## Translating
See [i18n.md](./i18n.i18n/i18n.md) for what to do. See [i18n.md](./i18n.i18n/i18n.md) for what to do.
As a special note, try to correctly use marks & symbols:
- Use `“”‘’` in place of `"'`, except when in a terminal
- Localize marks right, e.g. `“”` in English shall correspond to `„“` in German or `»«` in French, etc.
- Keep spaces consistent, e.g. `“”` will be rendered full-width in CJK font, so leave no space around them in CJK context
Hint: a Keyboard Layout other than default maybe helpful, especially those with AltGr/Level 3 Shift keys.
You can seek for help here, to do grammar extensions & leftovers. You can seek for help here, to do grammar extensions & leftovers.
## Coding ## Coding
1. Whether big or small, pull requests are welcome. 1. Any contribution welcome.
2. See file `TODO` for what's next. But don't limit imagination, do whatever you think is useful. 2. See file `TODO` for whats next. But dont limit imagination, do whatever you think is useful.
3. Keep the existing "way". Here are details: 3. Keep the existing “way”. Here are details:
- Think about the Unix Philosophy before doing. Try to suck less. - Think about the Unix Philosophy before doing. Try to suck less.
- Follow coding style & naming convention. - Follow coding style & naming convention.
- Think about the use cases: Web UI and/or command-line backend, average and/or advanced users - Think about the use cases: Web UI and/or command-line backend, average and/or advanced users
- Test the code well. Document if necessary. - Test the code well. Document if necessary.
- Don't forget internationalization & necessary accessibility features. - Dont forget internationalization & necessary accessibility features.
4. Finally, "rules". Just skim these, don't feel pressure as I trust you won't mistake: 4. Finally, “rules”. Just skim these, dont feel pressure as I trust you wont mistake:
- Don't leak development/test cache/junk to the repo. Please. - Dont leak development/test cache/junk to the repo. Please.
And never put pictures/executables/any big binary to this repo. Try uploading in an issue/discussion instead. And never put pictures/executable/any big binary to this repo. Try uploading in an issue/discussion instead.
- Don't connect to an online service to fetch resource.
If necessary, ask the user first.
- No more 3rd-party blackbox dependencies/assets, without explaining & using its most functionality. - No more 3rd-party blackbox dependencies/assets, without explaining & using its most functionality.
Consider using existing system programs, or implementing enough from scratch. Consider using existing system programs, or implementing enough from scratch.
If that really happened, make it optional (i.e. don't fail the load just for its non-existence), If that really happened, make it optional (i.e. dont fail the load just for its non-existence),
And don't push the dependency source code. And dont push the dependency source code.
For big dependencies, if you really love it, it's suggested to fork this repo & develop in your own way. For big dependencies, if you really love it, its suggested to fork this repo & develop in your own way.
- Don't make anti-features. Don't be someone yourself dislike most. - Dont connect to an online service to fetch resource.
If necessary, ask the user first. Again, such functionality shall be elsewhere.
- Dont make anti-features. Dont be someone yourself dislike most.
Examples: Examples:
- You can do: simple borders & stickers, scribbling, simple PostScript interpreter, another common printing protocol - You can do: simple borders & stickers, scribbling, simple PostScript interpreter, another common printing protocol
- Considering previous rule, discuss first: Bar/QR Code, formula, Native (non-Web) UI - Considering previous rule, discuss first: Bar/QR Code, formula, Native (non-Web) UI
- You shouldn't do: Way too fancy UI/editor, Cloud storage, camera integration & OCR - You shouldnt do: Way too fancy UI/editor, Cloud storage, camera integration & OCR
- Never consider: online account, non-free service integration, analysis/telemetry - Never consider: online account, non-free service integration, analysis/telemetry
- Please don't violate the license (GNU General Public License version 3) - Please dont violate the license (GNU General Public License version 3)
Modification to existing files are released under its existing license, Modification to existing files are released under its existing license,
mostly GPL3 or CC0, according to statement in readme. mostly GPL3 or CC0, according to statement in readme.
- If you want to preserve your copyright & use other license, create new file(s) for your work. - If you want to preserve your copyright & use other license, create new file(s) for your work.
But, never release your code under any non-free license. But, never release your code under any non-free license.
5. You can take any part of this project to do something else. It's also contribution! Let the ideas spread! 5. You can take any part of this project to do something else. Its also contribution! Let the ideas spread!
## Footnote ## Footnote
Nothing could go wrong. Trust yourself & try your best. Nothing could go wrong. Trust yourself & try your best.
Let's together build it better. Thank you. Lets together build it better. Thank you.

View File

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/sh
export version=`cat ../version` version=`cat ../version`
p4a apk --private .. --dist_name="cat-printer" --package="io.github.naitlee.catprinter" --name="Cat Printer" \ p4a apk --private .. --dist_name="cat-printer" --package="io.github.naitlee.catprinter" --name="Cat Printer" \
--icon=icon.png --version=$version --bootstrap=webview --window --requirements=android,pyjnius,bleak \ --icon=icon.png --version=$version --bootstrap=webview --window --requirements="`cat build-deps.txt`" \
--blacklist-requirements=sqlite3,openssl --port=8095 --arch=arm64-v8a --blacklist="blacklist.txt" \ --blacklist-requirements=sqlite3,openssl --port=8095 --arch=arm64-v8a --blacklist="blacklist.txt" \
--presplash=blank.png --presplash-color=black --add-source="advancedwebview" --orientation=user \ --presplash=blank.png --presplash-color=black --add-source="advancedwebview" --orientation=user \
--permission=BLUETOOTH --permission=BLUETOOTH_SCAN --permission=BLUETOOTH_CONNECT \ --permission=BLUETOOTH --permission=BLUETOOTH_SCAN --permission=BLUETOOTH_CONNECT \
--permission=BLUETOOTH_ADMIN --permission=ACCESS_FINE_LOCATION --permission=ACCESS_COARSE_LOCATION --permission=BLUETOOTH_ADMIN --permission=ACCESS_FINE_LOCATION --permission=ACCESS_COARSE_LOCATION $@

View File

@ -1,11 +1,12 @@
#!/bin/sh #!/bin/sh
export version=`cat ../version` version=`cat ../version`
rm -rf "dist" rm -rf "dist"
unzip -q "../cat-printer-bare-$version.zip" unzip -q "../cat-printer-bare-$version.zip"
mv "cat-printer" "dist" mv "cat-printer" "dist"
p4a apk --private "dist" --dist_name="cat-printer" --package="io.github.naitlee.catprinter" --name="Cat Printer" \ p4a apk --private "dist" --dist_name="cat-printer" --package="io.github.naitlee.catprinter" --name="Cat Printer" \
--icon=icon.png --version="$version" --bootstrap=webview --window --requirements=android,pyjnius,bleak \ --icon=icon.png --version="$version" --bootstrap=webview --window --requirements="`cat build-deps.txt`" \
--blacklist-requirements=sqlite3,openssl --port=8095 --arch=arm64-v8a --release \ --blacklist-requirements=sqlite3,openssl --port=8095 --arch=arm64-v8a --release \
--presplash=blank.png --presplash-color=black --add-source="advancedwebview" --orientation=user \ --presplash=blank.png --presplash-color=black --add-source="advancedwebview" --orientation=user \
--permission=BLUETOOTH --permission=BLUETOOTH_SCAN --permission=BLUETOOTH_CONNECT \ --permission=BLUETOOTH --permission=BLUETOOTH_SCAN --permission=BLUETOOTH_CONNECT \
--permission=BLUETOOTH_ADMIN --permission=ACCESS_FINE_LOCATION --permission=ACCESS_COARSE_LOCATION --permission=BLUETOOTH_ADMIN --permission=ACCESS_FINE_LOCATION --permission=ACCESS_COARSE_LOCATION $@

View File

@ -1,8 +1,13 @@
#!/bin/sh #!/bin/sh
export version=`cat ../version` version=`cat ../version`
export unsigned_apk=cat-printer-release-unsigned-$version-.apk unsigned_apk=cat-printer-release-unsigned-$version-.apk
export signed_apk=cat-printer-android-$version.apk signed_apk=cat-printer-android-$version.apk
$ANDROIDSDK/build-tools/32.0.0/zipalign 4 $unsigned_apk $signed_apk
$ANDROIDSDK/build-tools/32.0.0/apksigner sign --ks $1 $signed_apk if {
$ANDROIDSDK/build-tools/*/zipalign 4 $unsigned_apk $signed_apk;
$ANDROIDSDK/build-tools/*/apksigner sign --ks $1 $signed_apk;
}; then
echo "Complete! Moving APK..."
mv $signed_apk $signed_apk.idsig ../ mv $signed_apk $signed_apk.idsig ../
rm *.apk rm *.apk
fi

8
build-android/README.md Normal file
View File

@ -0,0 +1,8 @@
# Build for Android
The build environment shall be setup manually, since its a bit complex, and Im not so familiar with Android development.
See [Manual Steps](./manual-steps.md) to get started.
Android enthusiasts may help with automated build procedure, then for example F-Droid release would be possible.

View File

@ -0,0 +1 @@
async_timeout,typing-extensions,android,pyjnius,bleak

View File

@ -0,0 +1,32 @@
''' Some casual code to fix those alias files
in Android NDK llvm bin to symlinks instead
'''
import os
import sys
MAX_LENGTH = 256
ndk_path = sys.argv[1] if len(sys.argv) > 1 else input('Android NDK path: ')
bin_path = os.path.join(ndk_path, 'toolchains/llvm/prebuilt/linux-x86_64/bin/')
workdir = os.getcwd()
os.chdir(bin_path)
try:
for path in os.listdir():
# with this encoding it won't error when reading binary
file = open(path, 'r', encoding='iso8859-1')
data = file.read(MAX_LENGTH).strip()
file.close()
# inside the alias file is the filename that should be executed
# let's see if there is one
if os.path.isfile(data):
print('Will fix %s -> %s' % (path, data))
#os.remove(path)
os.rename(path, path + '.alias')
os.symlink(data, path)
finally:
os.chdir(workdir)

View File

@ -0,0 +1,338 @@
# Android Build Env Manual Setup
Expecting to cost about half a day.
Worthy to work on! This gives possibility to everything about Android in your mind!
Note: not being confirmed to 100% work yet. Be the first bird to try! Or bookmark this, arrange your time & come back later.
## Prepare
First, think about what will be your build environment. I choose to use a Ubuntu Docker container.
<details>
<summary>Expand Comparison</summary>
| | Minimal Ubuntu | Ubuntu | [Artix](https://artixlinux.org/) |
| :-------------------------- | :------------: | :----: | :------: |
| Base system<sup>1</sup> | | ✓ | ✓ |
| Pkg diversity | ✓ | ✓ | ✓ |
| Fresh pkg<sup>2</sup> | | | ✓ |
| Less hassle<sup>3</sup> | ✓ | | ✓ |
| Maintainability<sup>4</sup> | ✓ | | |
Note: “Minimal Ubuntu” can mean a Ubuntu [Docker](https://docs.docker.com/get-started/overview/) image, a Ubuntu chroot environment, etc.
1. In theory you can just have Ubuntu as base system, but see 2, 3, and 4.
2. Rolling distribution have newer packages offered.
It may give great experience in daily use, but will heavily bloat the update if many development packages are installed alltogether.
That said, Artix alone *worked* in those days. If you want, go ahead.
3. Mis-designs will stress you down. systemd will ruin your mood.
4. By operating in an isolated environment, a mess taking place inside wont affect the host.
(Some say Docker isnt intended to be “stateful”. But nothing is better in my mere knowledge.)
</details>
Before creating the build environment, lets prepare requirements of the outside.
### Space
Leave enough space for the isolated environment.
For Docker, maybe keep 3 GiB free in root directory.
Locate somewhere with at least 8 GiB free space,
Make 3 folders inside:
- `git-repo`, for git clones
- `android`, for Android SDK
- `p4a`, for manipulating python-for-android intermediate data
### Git Repositories
```bash
# Remember to use your path
DIR_GIT="/mnt/data/@/git-repo/"
cd $DIR_GIT
# Cat-Printer
git clone https://github.com/NaitLee/Cat-Printer.git
# Bleak, we need some Java code from its source
git clone https://github.com/hbldh/bleak.git
# AdvancedWebView, in order to give Android WebView capability to use <input type="file" />
git clone https://github.com/delight-im/Android-AdvancedWebView.git
# Let AdvancedWebView source code be in Cat-Printer building directory
ln -s ../../Android-AdvancedWebView/Source/library/src/main/java Cat-Printer/build-android/advancedwebview
```
### Android SDK
For most cases, following [python-for-android guide](https://python-for-android.readthedocs.io/en/latest/quickstart/#basic-sdk-install) will just work.
But Note: required by newer Gradle, use Android **platform 30** (or above) rather than 27.
After that, continue to [Fix the NDK](#fix-the-ndk).
----
If youre in China Mainland (you guessed it!), or prefer manual setup:
- Pick a working mirror. Currently theres [Tencent Cloud](https://mirrors.cloud.tencent.com/AndroidSDK/).
- Fetch & extract some archives, as shown in this table:
| Archive file | Top-level dir inside | Target directory |
| ----------------------------------- | ----------------------- | ----------------------------------- |
| `android-ndk-r23b-linux.zip` | `android-ndk-r23b` | `android/android-ndk-r23b` |
| `build-tools_r33-linux.zip` | `android-13` | `android/build-tools/33.0.0` |
| `commandlinetools-linux-8512546_latest.zip` | `cmdline-tools` | `android/cmdline-tools/latest` |
| `platform-30_r03.zip` | `android-11` | `android/platforms/android-30` |
| `platform-tools_r33.0.3-linux.zip` | `platform-tools` | `android/platform-tools` |
For example, you get `build-tools_r33-linux.zip`, see a folder `android-13` inside;
then you create `build-tools/` in `android/`, extract `android-13` there and rename it as `33.0.0`
So after that you will get:
```
android
├── android-ndk-r23b
├── build-tools
│   └── 33.0.0
├── cmdline-tools
│   └── latest
├── platforms
│   └── android-30
└── platform-tools
```
### Fix the NDK
The NDK (particularly, the llvm/clang binary directory) have some files that contain a path to other executable as their data.
System doesnt understand it. Lets replace them as symlinks:
```bash
# you may already have these from p4a guide
ANDROIDSDK="/mnt/data/@/android"
ANDROIDNDK="/mnt/data/@/android/android-ndk-r23b"
# feel free to check this script
python3 $DIR_GIT/Cat-Printer/build-android/fix-ndk-execs.py $ANDROIDNDK
```
## Setup
### Environment
```bash
# Install Docker Engine. This is for Arch-based OS
sudo pacman -Syu docker
# (I didnt try Docker Desktop)
```
For China Mainland users, configuring a mirror may be helpful. See https://mirrors.sjtug.sjtu.edu.cn/docs/docker-registry
after that, restart docker service, or reboot.
----
```bash
# lets create the container by first pulling the image
docker pull ubuntu:latest
# please, pass previously mentioned directories (or their parent) via -v parameter, we will access them here
# example: `-v /source1/android:/target1/android -v /source2/git-repo:/target2/git-repo`
docker create --name catbuild -v /mnt/data:/mnt/data --tty -i ubuntu
# From now on, start the container like this
docker start -i catbuild
```
----
OK, we are now inside the container shell. Set it up:
```bash
# (Optional) use a Ubuntu repository mirror
# sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
dpkg --add-architecture i386
apt update
apt upgrade
# find python-for-android dependencies here:
# https://python-for-android.readthedocs.io/en/latest/quickstart/#installing-dependencies
# there should be a command for Ubuntu that you can directly run
# ... though we need more
apt install -y python3-pip lld libffi-dev zip nano
# (Optional) use a pypi mirror
# pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install python-for-android cython bleak
```
### Source Code
The most tricky fact is that none of these things work out-of-the-box.
We should glue them up by hand.
```bash
# lets put those environment variables required by python-for-android here
nano ~/.bashrc
# append in the end. use your target paths!
export ANDROIDSDK="/mnt/data/@/android"
export ANDROIDNDK="/mnt/data/@/android/android-ndk-r23b"
export ANDROIDAPI="30"
export NDKAPI="21"
# after that, apply these
source ~/.bashrc
```
----
```bash
# define shortcut(s). use your target paths!
DIR_GIT="/mnt/data/@/git-repo/"
DIR_P4A="/usr/local/lib/python3.10/dist-packages/pythonforandroid/"
# p4a will generate some intermediate data. “expose” this to the host for convenient manipulation.
mkdir -p ~/.local/share/
ln -s /mnt/data/@/p4a/ ~/.local/share/python-for-android
# give p4a the bleak recipe. fortunately, p4a will resolve this symlink
ln -s $DIR_GIT/bleak/bleak/backends/p4android/recipes/bleak $DIR_P4A/recipes/bleak
```
----
At this point, do some code patch.
AdvancedWebView have a deprecated function override that fails the compile. Remove it.
```bash
cd $DIR_GIT/Android-AdvancedWebView/Source/library/src/main/java/im/delight/android/webview/
# any editor is okay. you can do it at host side with graphical editor.
nano AdvancedWebView.java
# search for `public void onUnhandledInputEvent`, remove (or comment out) the *entire function body*
```
Modify p4a webview bootstrap to use AdvancedWebView instead
```bash
# copy source file to somewhere easy to access
cd $DIR_GIT
cp $DIR_P4A/bootstraps/webview/build/src/main/java/org/kivy/android/PythonActivity.java ./
# some sed script doing the dirty work
sed -i 's/import android.webkit.WebView;/import im.delight.android.webview.AdvancedWebView;/' PythonActivity.java
sed -i -r 's/\bWebView\b/AdvancedWebView;/g' PythonActivity.java
```
Not the end yet —
You really want to use a graphical editor now, except if you enjoy vim or emacs...
- (At host side) Open the file with an editor
- Search & remove these two `@Override` decorators:
```java
//@Override
public boolean shouldOverrideUrlLoading
//@Override
public void onPageFinished
```
- Add this after the line `protected void onActivityResult`:
```java
// pass this activity to AdvancedWebView instance, to get <input type="file" /> really work
if ( requestCode == 51426 ) {
mWebView.onActivityResult(requestCode, resultCode, intent);
return;
}
```
- (Optional) Remove the problematic “Tap again to close the app” behavior:
Find function `public boolean onKeyDown`, remove everything inside except the `return` clause.
----
```bash
# save the modification, overwrite the original
# (you can make a backup if you feel it right)
cp $DIR_GIT/PythonActivity.java $DIR_P4A/bootstraps/webview/build/src/main/java/org/kivy/android/PythonActivity.java
# customize the loading page with Cat-Printer assets
cp $DIR_GIT/Cat-Printer/www/_load.html $DIR_GIT/Cat-Printer/www/icon.svg $DIR_P4A/bootstraps/webview/build/webview_includes/
```
## Build
### Debug Build
*\*Phew\**, it should be ready. Now try to build a debug version:
```bash
# always cd here
cd $DIR_GIT/Cat-Printer/build-android/
# <dot><slash><0><tab>
./0-build-android.sh
# again, feel free to check this file
```
The initial build will cost some time.
p4a will do:
- Download some source code from Internet, notably `python3` and some essential packages like `pyjnius`, `pyffi`, etc.
- Build all of them
- Build Cat-Printer code to Cython, gather everything together
- Download a Gradle package, give those assets to Gradle to complete the build.
TODO: find a way to get Gradle in China Mainland ~~without any circumvention~~
----
It worked? Congratulations! Now test your built package with an Android phone.
(Note that if youve previously installed my distribution, uninstall it first, to solve signature conflict.)
It didnt? **Dont panic!** Check the message to see whats wrong, try to fix it.
Get a problem? **Say whats up in Issue/Discussion.**
Build process messed up? Changes not applied? Execute `./2-clean-up-build.sh` to clean up, then redo the build.
Other scripts inside `build-android/` may be helpful too.
### Release Build
Its best to publish a release build. In contrast to debug build, release build have smaller size, optimized, and signed for authority.
Before start, read [development.md](../development.md) to setup for a “pure” bundle, and build one.
Okay, now lets generate your key, to be used to sign the apk:
```bash
# keytool is of Java. use from your build environment.
# keep this file secret! put outside of git directory, dont lose it.
keytool -genkey -v -keystore mykeyfile.key -keyalg RSA -keysize 2048 -validity 18250 -alias mykey
```
```bash
# always cd here
cd $DIR_GIT/Cat-Printer/build-android/
# <dot><slash><3><tab>
# pass the path to keyfile as parameter
./3-formal-build.sh mykeyfile.key
# again, feel free to check this file
```
This will cost a bit more time than debug build.
Note: Im unsure if (another or the first) Gradle is being downloaded in this step.
If it also worked, congrats again!
(On Android, the debug build conflicts with a signed release build. Uninstall one to install the other.)
Try the ultimate helper `1-build.sh`, if you also have everything in [development.md](../development.md) done.
## The End
You made it! You now have ability to contribute much more, outside of Cat-Printer. Try to bring an app in your mind to reality, with just Python, Web, and this build environment.

View File

@ -103,7 +103,13 @@ with zipfile.ZipFile(bundle_name, 'w', zipfile.ZIP_DEFLATED) as bundle:
fullpath = os.path.join(path, name) fullpath = os.path.join(path, name)
bundle.write(fullpath, os.path.join(bundle_sub_dir, fullpath)) bundle.write(fullpath, os.path.join(bundle_sub_dir, fullpath))
if edition == 'windows': if edition == 'windows':
os.chdir('python-win32-amd64-embed') for path, dirs, files in os.walk('bleak_winrt'):
if path.endswith('__pycache__'):
continue
for name in files:
fullpath = os.path.join(path, name)
bundle.write(fullpath, os.path.join(bundle_sub_dir, fullpath))
os.chdir('python-w32')
for path, dirs, files in os.walk('.'): for path, dirs, files in os.walk('.'):
if path.endswith('__pycache__'): if path.endswith('__pycache__'):
continue continue

View File

@ -3,125 +3,137 @@
## Overview ## Overview
This application have a Client/Server module, but it's just locally. This application have a Client/Server module, but just locally.
The backend is in Python 3, aiming to have fewest dependencies, and in fact currently have just `bleak`. The backend is in Python 3, aiming to have fewest possible dependencies, and currently have just `bleak`.
This can ensure the simplicity of the core part. This can keep the core part simple, maximize reusability.
And the frontend is in a "old good" way, that use no "framework". The Web frontend uses no “framework”. It shouldnt, in my opinion.
The command-line interface (CLI) could invoke other commands, to help the process. The command-line interface (CLI) could invoke other commands to extend functionality.
Currently it may invoke `magick` and `gs`, for ImageMagick and Ghostscript respectively. At the moment it may invoke `magick` and `gs`, for ImageMagick and Ghostscript respectively.
My workspace stack is Linux/GNU/Artix/KDE/VSCodium, if you're interested.
For Android, GNU/Linux is required, though.
The Android version is built with [python-for-android](https://python-for-android.readthedocs.io/en/latest/). The Android version is built with [python-for-android](https://python-for-android.readthedocs.io/en/latest/).
In our case it's complicated, don't go blindly if you don't want to waste your time. See [Android Readme](./build-android/README.md) to get started, but dont forget to finish this document.
There are too many hacks to be done, before and after. Let me summarize them later...
By the way, feel free to look at file `dev-diary.txt` By the way, feel free to look at `dev-diary.txt`.
My workspace stack is Linux/GNU/Artix/KDE/VSCodium, if youre interested.
## Get Dependencies ## Get Dependencies
### Basic ### Basic
Just clone this repo first! 0. Clone this repository
1. Install python3
2. Get Bleak BLE library:
`pip3 install bleak`
1. Get Bleak BLE lib: Alright, you are well done for basic development & debugging. See [files](#files) section for what all the files do.
`pip install bleak`
Alright, you are already well done for basic development. See [files](#files) section for what all the files do. For more stuffs, read on...
For more, read on...
### Optional ### Optional
Sorry, I'm not a dev package manager enthusiast. Sorry, Im not a dev package manager enthusiast.
If there are something better to organize these, feel free to discuss in issue. If something better can be done to organize these, feel free to discuss.
- Install [ImageMagick](https://imagemagick.org/) and [Ghostscript](https://ghostscript.com/) - Install [ImageMagick](https://imagemagick.org/) and [Ghostscript](https://ghostscript.com/)
- Now you can enjoy more command line features. And could make it better or debug problems - They have big chance to be pre-installed
- Install TypeScript on Node.js `npm` - With these you can enjoy more command line features
`npm --global install typescript` <!-- TODO make Node.js dep optional, lets use Deno or Bun instead. -->
You may need root privilege on GNU/Linux (i.e. prefix `sudo`) - Install TypeScript:
Now the `0-transpile.sh` will work, you're ready to deal with compatibility - Its adviced to separate [Node.js/npm](https://nodejs.org/) executables from package manager, to avoid system inconsistency
- Put the Bleak pip installation as `build-common/bleak` - After setting up it, do `npm install --global typescript`. You may need root privilege on \*nix systems (prefix `sudo`)
- You need this in order to bundle a "pure" or "windows" release - Now the `0-transpile.sh` will work, youre ready to deal with compatibility
- See [Files](#files) section about `bundle.py` - Gather Bleak:
- Get an Windows 64-bit embeddable Python, extract to `build-common/python-win32-amd64-embed` - Get [Bleak package](https://pypi.org/project/bleak/#files), the `.whl` file in “Built Distribution”
- You may remove the "bloated" parts inside, notably `libssl`, `libcrypto`, `sqlite3` and `pydoc`, of both `dll`/`pyd` files and in `python<version>.zip`, if have any. - `.whl` is a zip file. Unzip it as usual, put `bleak` to the folder `build-common/`
- Now you're able to bundle a "windows" edition, via `python3 bundle.py -w` - Now that you can bundle a “pure” release
- Get [Bleak winrt](https://pypi.org/project/bleak-winrt/#files), pay special attention to version, e.g.:
- `bleak_winrt-1.1.1-cp310-cp310-win32.whl` means to be used with CPython 3.10 under 32-bit Windows (or WoW64)
- Unzip it, put `bleak_winrt` to the folder `build-common/`
- Now that you can also bundle a “windows” release
- Also see [Files](#files) section about `bundle.py`
- Get an Windows embeddable Python, extract to `build-common/python-w32`
- You may remove some “bloats”, notably `libssl`, `libcrypto`, `sqlite3` and `pydoc`, of both `dll`/`pyd` files and inside `python<version>.zip`, if there are any
- Now youre able to bundle a “windows” edition, via `python3 bundle.py -w`
- Get a [vConsole](https://www.npmjs.com/package/vconsole) script, put to `www` as `vconsole.js` - Get a [vConsole](https://www.npmjs.com/package/vconsole) script, put to `www` as `vconsole.js`
Now you're ready to debug in browsers without a dev panel, by double-tapping "Cat Printer" title in the UI Now youre ready to debug in browsers without a dev panel, by double-tapping status message
## Files ## Files
- `server.py` - A Web server that: - `server.py` - A Web server that:
- Is single threaded & with static handler, for some reasons - Is single threaded & with static handler, for some reasons
- Serves static Web files, that are in folder `www` - Serves static Web files, that are in folder `www`
- Opens a Web browser once launched, unless specify the `-s` command-line parameter - Tries to open a Web browser once launched, unless specify `-s`
- Only listen to localhost, unless specify the `-a` command-line parameter - Only listens to localhost, unless specify `-a`
- Handles API requests via `POST` - Handles API requests via `POST` requests
- Handles frontend configuration - Handles frontend configuration
- Few CUPS/IPP features included - Very basic CUPS/IPP feature included
- Interacts with `printer.py`, for the printer driver - Interacts with `printer.py`, for the printer driver
- `printer.py` - The core printer driver: - `printer.py` - The core printer driver:
- Have the `PrinterDriver` class, to be reused - Have the `PrinterDriver` class, to be reused
- Have a command-line interface. Can be invoked in a shell, to do things directly - Have a command-line interface. Can be invoked in a shell, to do things directly
- `printer_lib/*` - Some helpers:
- These are also intended to be reused, and are in Public Domain under CC0 license
- Especially `commander.py`, which contains the printers BLE protocol
- `.pylintrc` - Pylint RC file: - `.pylintrc` - Pylint RC file:
- Include it for better experience browsing the code - Include it for better experience browsing the code
- `www/main.js` - Main frontend script: - `www/main.js` - Main frontend script:
- The script for direct modification in development - The script for direct modification in development
- No need to care "compatibility". Transpile the scripts when release. - No need to care “compatibility”. Transpile the scripts when release
- `www/image.js` - Image manipulation functions: - `www/image.js` - Image manipulation functions:
- Implementations for some grayscale/monochrome filters on a image (HTML `<canvas>` `ImageData`) - Now is transpiled from `wasm/image.ts`, which is intended for WebAssembly implementation, but unfortunately slower with it
- And PBM image file format, a very simple mono bitmap format. - Have some grayscale/monochrome filters for HTML `<canvas>` `ImageData`
- And PBM image file format, a very simple mono bitmap format, helpful to be read & used
- `www/main.comp.js` - Compatibility script: - `www/main.comp.js` - Compatibility script:
- Transpiled with TypeScript, for fallback on old browsers - Transpiled from other scripts around for falling back on old browsers
- Bundled all required scripts, see file `0-transpile.sh` - Bundled all required scripts, see file `0-transpile.sh`
- Is not there by default. Transpile it yourself - Isnt there unless you transpile
- `www/i18n*` - Scripts about I18n: - `www/i18n*` - Scripts about I18n:
- See [i18n.md](i18n.i18n/i18n.md) - See [i18n.md](i18n.i18n/i18n.md)
- `www/*.js` - Other scripts: - `www/*.js` - Other scripts:
- Small but useful, just look at them directly - Small but useful, just look at them directly
- Most are in Public Domain - Most are in Public Domain under CC0 license
- `www/jslicense.html` - Dedicated JavaScript License information - `www/jslicense.html` - Dedicated JavaScript License Information, useful for user reference & LibreJS indentification
- `www/lang/*.json` - Language files for both front- & back-end - `www/lang/*.json` - Language files for both front- & back-end
- `version` - The version tag, as a file - `version` - The version tag, as a file
- Modify it to determine the version used in build scripts - Modify it to determine the version used in build scripts
- Don't leave a trailing new line - Dont leave a trailing new line
- `N-*.sh` - Shell files: - `N-*.sh` - Shell files:
- Helpers for development convenience - Helpers for development convenience
- Quickly invoke with `./N<tab><enter>` - Quickly invoke with `./N<tab><enter>`
- `build-common/bundle.py` - Bundler for "windows", "pure" and "bare" editions - `build-common/bundle.py` - Bundler for “windows”, “pure” and “bare” editions
- You can define what to include or not in this script, just modify directly, while trying to not alter other - You can define what to include or not in this script, just modify directly, while trying to not alter other
- Adviced to transpile scripts before bundling - Adviced to transpile scripts before bundling
- To do the builds you should be in the build dir: `cd build-common` - To do the builds you should be in the build dir: `cd build-common`
- With `bleak` there you're able to bundle a "pure" edition via just `python3 bundle.py` - With `bleak` there youre able to bundle a “pure” edition via just `python3 bundle.py`
- In any case you're able to bundle a "bare" edition, via `python3 bundle.py -b` - In any case youre able to bundle a “bare” edition, via `python3 bundle.py -b`
- Bundle a "windows" edition with `-w` switch in place of `-b` - Bundle a “windows” edition with `-w` switch in place of `-b`
- You may put a version code as last parameter - You may put version tag as last parameter
- Resulting zip files will be in repo's root directory - Resulting zip files will be in repos root directory
- `build-common/0-bundle-all.sh` - Bundle all editions at once - `build-common/0-bundle-all.sh` - Bundle all editions at once
<!-- TODO: split to Android docs -->
- `build-android/0-build-android.sh` - The dev build script: - `build-android/0-build-android.sh` - The dev build script:
- Invokes `python-for-android` - Invokes `python-for-android`
- Defines many things - Defines many things
- Just builds using the current repo state - Just builds using the current repo state
- **Doesn't** work out-of-the-box. Again, please wait for me to summarize the hacks... - **Doesnt** work out-of-the-box. Again, please wait for me to summarize the hacks...
- `build-android/3-formal-build.sh` - The "formal" build script: - `build-android/3-formal-build.sh` - The “formal” build script:
- Unlike the dev version, this takes files from a "bare" edition zip - Unlike the dev version, this takes files from a “bare” edition zip
- Also unlike dev, this doesn't enforce the custom blacklist, since "bare" is already minimal - Also unlike dev, this doesnt enforce the custom blacklist, since “bare” is already minimal
- Now it builds a "release" version. In order to be installed on Android, you need to sign it. Know more on Internet - Now it builds a “release” version. In order to be installed on Android, you need to sign it. Know more on Internet
### Be aware that... ### Be aware that...
If there are development files that are not meant to be in this public repo, please add to `.gitignore`. If there are development files that are not meant to be in this public repo, please add to `.gitignore`.
And don't put too-big files, especially binary. Not everyone have good connection to GitHub. And dont put big binary files, because not everyone have good connection to GitHub.
Same applies to most feature-bloated 3rd party libraries. Same applies to most feature-bloated 3rd-party libraries. Try your best to avoid introducing more dependencies.
In our case you should try your best to avoid introducing more dev dependencies. Though, its reasonable to invoke a tool that is already on the system, or always accepted by users / very easy to install
Tip: it's reasonable to use (invoke) a tool that is already on the system, or always accepted by users / very easy to install

View File

@ -74,7 +74,8 @@ try:
from bleak import BleakClient, BleakScanner from bleak import BleakClient, BleakScanner
from bleak.backends.device import BLEDevice from bleak.backends.device import BLEDevice
from bleak.exc import BleakError, BleakDBusError from bleak.exc import BleakError, BleakDBusError
except ImportError: except ImportError as error:
raise error
fatal( fatal(
i18n('please-install-bleak-via-pip'), i18n('please-install-bleak-via-pip'),
' $ pip3 install bleak', ' $ pip3 install bleak',

View File

@ -19,8 +19,8 @@ class I18nLib():
data: dict = {} data: dict = {}
def __init__(self, search_path='lang', lang=None, fallback=None): def __init__(self, search_path='lang', lang=None, fallback=None):
self.lang = lang or locale.getdefaultlocale()[0].replace('_', '-')
self.fallback = fallback or 'en-US' self.fallback = fallback or 'en-US'
self.lang = lang or (locale.getdefaultlocale()[0] or fallback).replace('_', '-')
with open(os.path.join(search_path, self.fallback + '.json'), with open(os.path.join(search_path, self.fallback + '.json'),
'r', encoding='utf-8') as file: 'r', encoding='utf-8') as file:
self.data = json.load(file) self.data = json.load(file)

View File

@ -78,7 +78,7 @@ class PrinterServerHandler(BaseHTTPRequestHandler):
'is_android': False, 'is_android': False,
'scan_time': 4.0, 'scan_time': 4.0,
'dry_run': False, 'dry_run': False,
'energy': 0.2 'energy': 64
}) })
_settings_blacklist = ( _settings_blacklist = (
'printer', 'is_android' 'printer', 'is_android'

View File

@ -1 +1 @@
0.6.0.2 0.6.1

View File

@ -98,7 +98,7 @@
"all-users-and-developers": "Alle Tester & Benutzer", "all-users-and-developers": "Alle Tester & Benutzer",
"everyone-is-awesome": "Ihr seid alle fantastisch", "everyone-is-awesome": "Ihr seid alle fantastisch",
"license": "Lizenz", "license": "Lizenz",
"exiting": "Beende...", "exiting": "Beende",
"dark-theme": "Dunkles Design", "dark-theme": "Dunkles Design",
"high-contrast": "Hoher Kontrast", "high-contrast": "Hoher Kontrast",
@ -124,7 +124,7 @@
"javascript-maincompjs-description": "Transpilieren der Entwicklungsskripte für verbesserte Kompatibilität.", "javascript-maincompjs-description": "Transpilieren der Entwicklungsskripte für verbesserte Kompatibilität.",
"javascript-loaderjs-description": "Dynamisches Laden von Skripten und Fallbacks.", "javascript-loaderjs-description": "Dynamisches Laden von Skripten und Fallbacks.",
"javascript-polyfilljs-description": "Nachrüsten von Funktionen in nicht unterstützten Browsern", "javascript-polyfilljs-description": "Nachrüsten von Funktionen in nicht unterstützten Browsern",
"javascript-i18nextjs-description": "I18n \"Erweiterungen\"", "javascript-i18nextjs-description": "I18n „Erweiterungen“",
"javascript-i18njs-description": "Lokalisierung und Übersetzung", "javascript-i18njs-description": "Lokalisierung und Übersetzung",
"javascript-imagejs-description": "Bildbearbeitung", "javascript-imagejs-description": "Bildbearbeitung",
"javascript-accessibilityjs-description": "Barrierefreiheit", "javascript-accessibilityjs-description": "Barrierefreiheit",

View File

@ -142,7 +142,7 @@
"javascript-maincompjs-description": "All following development scripts, transpiled for compatibility.", "javascript-maincompjs-description": "All following development scripts, transpiled for compatibility.",
"javascript-loaderjs-description": "For dynamically loading other scripts, and fallback if there are problems.", "javascript-loaderjs-description": "For dynamically loading other scripts, and fallback if there are problems.",
"javascript-polyfilljs-description": "Add features which are not supported by old browsers.", "javascript-polyfilljs-description": "Add features which are not supported by old browsers.",
"javascript-i18nextjs-description": "I18n \"extensions\"", "javascript-i18nextjs-description": "I18n “extensions”",
"javascript-i18njs-description": "For internationalization (language support)", "javascript-i18njs-description": "For internationalization (language support)",
"javascript-imagejs-description": "For canvas image manipulation", "javascript-imagejs-description": "For canvas image manipulation",
"javascript-accessibilityjs-description": "Accessibility features", "javascript-accessibilityjs-description": "Accessibility features",