The foremost source of Android apps is the Google Play Store. This is not great, because the Google Play Store requires you to sign in to a Google account on your Android phone, which of course allows Google to track your every movement. There is no technical reason that you should have to log in to a Google account to download Android apps, given that the apps are free and everyone receives the same version. The sole purpose is to allow Google to spy on you and monetize your personal life.
To work around the problem, dontbeevilmirror is a simple anonymizing proxy for Google Play. On the frontend, you navigate an interface similar to Google Play to download and install apps. On the backend, these requests are anonymized and filtered through a shared Google account that I have registered for the project. Furthermore, once an app is downloaded once, a copy is saved so that future downloads don't go to Google.
(This project is heavily unfinished.)
To compile the googlecurl binary:
- Install Go
- Go into
googlecurland rungo build
To use the API library:
- Install Poetry
- Go into
gplayapiand runpoetry install - Make sure compiled googlecurl is on the PATH
- Start a shell with
poetry run python from dontbeevilmirror.api import GooglePlay, InitialAuthInfo, AuthInfo, CheckinInfo, Credentials; g = GooglePlay()- For initial login,
g.perform_initial_login(email, password)and then save the result ofg.get_credentials() - For restoring session,
g.set_credentials(creds) - API methods:
g.search(query)(doesn't require auth),g.get_details_single(app_id),g.get_details_multiple(*app_ids),g.get_download(app),g.check_authentication()
To use the command-line tool:
- Not finished yet
To run the webserver:
- Install Docker Compose
- Go into
serverand copy.env.sampleto.env - Fill in
GOOGLE_EMAILandGOOGLE_PASSWORD, generate a random string forPOSTGRES_PASSWORD, pick fake values forB2_BUCKETandB2_URL_BASE(they don't matter ifB2_USE_MOCK=1) - To use real B2, set
B2_USE_MOCK=0, fill inB2_KEY_IDandB2_KEY_SECRET, setB2_BUCKET, and setB2_URL_BASEto something likehttps://example.com/file/whereexample.comis a CNAME to your Backblaze CDN server - Run
docker-compose up
To compile the Android app:
- Install JDK 17 and make it available (
JAVA_HOMEetc) - Install Android SDK 32 and make it available (
ANDROID_HOMEetc). One way is with sdkmanager - Go into
appand run./gradlew build - Compiled app is in
./app/build/outputs/apk/debug/app-debug.apk - Install with
adb install
The current setup I have in production is a simple VPS on BuyVM,
because that is very economical. I then have this systemd unit file
installed at /etc/systemd/system/dontbeevilmirror.service:
[Unit]
Description=dontbeevilmirror
Requires=docker.service
After=docker.service
StartLimitBurst=3
StartLimitIntervalSec=60
[Service]
Type=exec
ExecStart=docker compose --file /opt/dontbeevilmirror/docker-compose.yml --env-file /opt/dontbeevilmirror/env up --abort-on-container-exit --no-build --pull=never
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
There is then an instance of Docker Registry running on the VPS. When
I want to deploy, I build the Docker image locally and push it to the
VPS registry. Then I ssh in, pull the image from the local registry,
tag it as dontbeevilmirror, and restart the systemd service. It's
pretty simple. The only other part is the .env file from my local
machine needs to end up in /opt/dontbeevilmirror/env with the
production credentials.
As the server is HTTP only, I have Caddy set up with this
/etc/caddy/Caddyfile to terminate TLS and obtain certs:
{
auto_https disable_redirects
}
dontbeevilmirror.example.com {
reverse_proxy localhost:8080
}
dontbeevilmirror.example.com:5443 {
reverse_proxy localhost:5000
}
The reverse-engineered logic for accessing the Google Play API was determined by inspection of the code of Raccoon, which is provided under the terms of the Apache License.
Adaption to Python was aided by inspection of the code of googleplay-api, which is provided under the terms of the BSD License and GNU Public License. Note that no code is incorporated from this project, and copy-left provisions do not apply since, under U.S. law, implementations are not creative works and hence not copyrightable when they are the only possible way to accomplish the task at hand (e.g. satisfying Google authentication requirements).
Some icons were taken from Material Icons, which is provided under the terms of the Apache License.
Some assets were taken from Streamline Emoji, which is provided under the terms of the CC-BY License.
Figuring out the correct XML files to display a navbar was helped by referencing NavigationComponents-Tutorials, which is provided under the terms of the MIT License.
Some debugging assistance on the more bullshit aspects of Android XML files was provided by ChatGPT by OpenAI. The licensing status of code provided by ChatGPT cannot be authoritatively determined, but the use cases exercised in this project were unlikely to provide any information that was not also available on Stack Overflow.