mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-08-27 15:23:32 +02:00
nobuild
Migrate Free Games Claimer to remaster upstream
This commit is contained in:
@@ -1,20 +1,53 @@
|
|||||||
- Added support for configuring extra environment variables via the `env_vars` add-on option alongside config.yaml. See https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2 for details.
|
## 2.0.0 (2026-07-17)
|
||||||
|
|
||||||
|
- Replaced the abandoned `vogler/free-games-claimer` upstream with
|
||||||
|
`P-Adamiec/Free-Games-Claimer-Remaster`.
|
||||||
|
- Reworked the image build for the remaster's Python, Chromium, TurboVNC, and
|
||||||
|
noVNC runtime on both amd64 and aarch64.
|
||||||
|
- Preserved the previous default one-shot behavior and Epic, Prime Gaming, and
|
||||||
|
GOG store selection.
|
||||||
|
- Kept noVNC on port 6080 for upgrade compatibility.
|
||||||
|
- Added `RUN_ONCE` and `STORES` options while retaining `CMD_ARGUMENTS` as a
|
||||||
|
deprecated compatibility input.
|
||||||
|
- Added an automatic, idempotent migration of legacy Epic, Prime Gaming, and
|
||||||
|
GOG JSON claim history into the remaster SQLite database.
|
||||||
|
- Preserved legacy files for rollback and documented the required one-time
|
||||||
|
Chromium login when a Firefox session cannot be migrated.
|
||||||
|
- Pinned the reviewed upstream source commit and paused generic automatic
|
||||||
|
updates so the add-on's independent `2.x` version cannot regress to `1.x`.
|
||||||
|
- Updated the configuration template, upstream metadata, and documentation.
|
||||||
|
- Added support for configuring extra environment variables via the `env_vars`
|
||||||
|
add-on option.
|
||||||
|
|
||||||
## 1.8 (2025-05-17)
|
## 1.8 (2025-05-17)
|
||||||
- Update to latest version from vogler/free-games-claimer (changelog : https://github.com/vogler/free-games-claimer/releases)
|
|
||||||
|
- Update to latest version from vogler/free-games-claimer (changelog: https://github.com/vogler/free-games-claimer/releases)
|
||||||
|
|
||||||
## 1.7 (2025-03-08)
|
## 1.7 (2025-03-08)
|
||||||
- Update to latest version from vogler/free-games-claimer (changelog : https://github.com/vogler/free-games-claimer/releases)
|
|
||||||
|
- Update to latest version from vogler/free-games-claimer (changelog: https://github.com/vogler/free-games-claimer/releases)
|
||||||
|
|
||||||
## 1.6-6 (2024-12-29)
|
## 1.6-6 (2024-12-29)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.6-5 (2024-12-13)
|
## 1.6-5 (2024-12-13)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.6-4 (2024-12-07)
|
## 1.6-4 (2024-12-07)
|
||||||
- ⚠ MAJOR CHANGE : switch to the new config logic from homeassistant. Your configuration files will have migrated from /config/hassio_addons/free_games_claimer in a folder only accessible from my Filebrowser addon called /addon_configs/db21ed7f_free_games_claimer. This avoids the addon to mess with your homeassistant configuration folder, and allows to backup the options. For more information, see here : https://developers.home-assistant.io/blog/2023/11/06/public-addon-config/
|
|
||||||
|
- Major change: switch to the new Home Assistant add-on configuration logic.
|
||||||
|
Configuration files were migrated from
|
||||||
|
`/config/hassio_addons/free_games_claimer` to the private add-on configuration
|
||||||
|
directory available through compatible file browser add-ons.
|
||||||
|
|
||||||
## 1.6-3 (2024-12-05)
|
## 1.6-3 (2024-12-05)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.6-2 (2024-12-05)
|
## 1.6-2 (2024-12-05)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.6 (2023-12-30)
|
## 1.6 (2023-12-30)
|
||||||
@@ -28,18 +61,23 @@
|
|||||||
## 1.4 (2023-05-27)
|
## 1.4 (2023-05-27)
|
||||||
|
|
||||||
- Update to latest version from vogler/free-games-claimer
|
- Update to latest version from vogler/free-games-claimer
|
||||||
|
|
||||||
## 1.4-5 (2023-05-26)
|
## 1.4-5 (2023-05-26)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.4-4 (2023-05-26)
|
## 1.4-4 (2023-05-26)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.4-3 (2023-05-26)
|
## 1.4-3 (2023-05-26)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## 1.4-2 (2023-05-25)
|
## 1.4-2 (2023-05-25)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|
||||||
## NOT_WORKING (2023-05-22)
|
## NOT_WORKING (2023-05-22)
|
||||||
|
|
||||||
- Minor bugs fixed
|
- Minor bugs fixed
|
||||||
|
|||||||
@@ -1,91 +1,14 @@
|
|||||||
#============================#
|
#============================#
|
||||||
# ALEXBELGIUM'S DOCKERFILE #
|
# ALEXBELGIUM'S DOCKERFILE #
|
||||||
#============================#
|
#============================#
|
||||||
# _.------.
|
#=== Home Assistant Add-on ===#
|
||||||
# _.-` ('>.-`"""-.
|
|
||||||
# '.--'` _'` _ .--.)
|
|
||||||
# -' '-.-';` `
|
|
||||||
# ' - _.' ``'--.
|
|
||||||
# '---` .-'""`
|
|
||||||
# /`
|
|
||||||
#=== Home Assistant Addon ===#
|
|
||||||
|
|
||||||
#################
|
ARG BUILD_FROM="debian:bookworm-slim"
|
||||||
# 1 Build Image #
|
|
||||||
#################
|
|
||||||
|
|
||||||
ARG BUILD_FROM
|
|
||||||
ARG BUILD_VERSION
|
|
||||||
FROM ${BUILD_FROM}
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
##################
|
|
||||||
# 2 Modify Image #
|
|
||||||
##################
|
|
||||||
|
|
||||||
# Set S6 wait time
|
|
||||||
ENV S6_CMD_WAIT_FOR_SERVICES=1 \
|
|
||||||
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
|
|
||||||
S6_SERVICES_GRACETIME=0
|
|
||||||
|
|
||||||
##################
|
|
||||||
# 3 Install apps #
|
|
||||||
##################
|
|
||||||
|
|
||||||
# Add rootfs
|
|
||||||
COPY rootfs/ /
|
|
||||||
RUN find . -type f \( -name "*.sh" -o -name "run" -o -name "finish" \) -print -exec chmod +x {} \;
|
|
||||||
|
|
||||||
# Uses /bin for compatibility purposes
|
|
||||||
# hadolint ignore=DL4005
|
|
||||||
RUN if [ ! -f /bin/sh ] && [ -f /usr/bin/sh ]; then ln -s /usr/bin/sh /bin/sh; fi && \
|
|
||||||
if [ ! -f /bin/bash ] && [ -f /usr/bin/bash ]; then ln -s /usr/bin/bash /bin/bash; fi
|
|
||||||
|
|
||||||
# Modules
|
|
||||||
ARG MODULES="00-banner.sh 01-custom_script.sh"
|
|
||||||
|
|
||||||
# Automatic modules download
|
|
||||||
COPY ha_automodules.sh /ha_automodules.sh
|
|
||||||
RUN chmod 744 /ha_automodules.sh && /ha_automodules.sh "$MODULES" && rm /ha_automodules.sh
|
|
||||||
|
|
||||||
# Manual apps
|
|
||||||
ENV PACKAGES=""
|
|
||||||
|
|
||||||
# Automatic apps & bashio
|
|
||||||
COPY ha_autoapps.sh /ha_autoapps.sh
|
|
||||||
RUN chmod 744 /ha_autoapps.sh && /ha_autoapps.sh "$PACKAGES" && rm /ha_autoapps.sh
|
|
||||||
|
|
||||||
################
|
|
||||||
# 4 Entrypoint #
|
|
||||||
################
|
|
||||||
|
|
||||||
# Add entrypoint
|
|
||||||
ENV S6_STAGE2_HOOK=/ha_entrypoint.sh
|
|
||||||
COPY ha_entrypoint.sh /ha_entrypoint.sh
|
|
||||||
RUN chmod 777 /ha_entrypoint.sh
|
|
||||||
|
|
||||||
# Install bashio
|
|
||||||
COPY bashio-standalone.sh /usr/local/lib/bashio-standalone.sh
|
|
||||||
RUN chmod 0755 /usr/local/lib/bashio-standalone.sh
|
|
||||||
|
|
||||||
RUN \
|
|
||||||
# Change data folder
|
|
||||||
sed -i "s|/fgc|/data|g" /usr/local/bin/docker-entrypoint.sh && \
|
|
||||||
# Run scripts only once
|
|
||||||
sed -i "1a if [ -f /done ]; then exit 0; fi && touch /done" /ha_entrypoint.sh && \
|
|
||||||
sed -i "s=x11vnc=[[ \"\$(ps aux | grep \"x11vnc\" | grep -v grep)\" ]] || x11vnc=g" /usr/local/bin/docker-entrypoint.sh && \
|
|
||||||
# Update playwright
|
|
||||||
npx playwright install-deps && \
|
|
||||||
npx playwright install
|
|
||||||
|
|
||||||
WORKDIR /data
|
|
||||||
ENTRYPOINT [ "/usr/bin/env" ]
|
|
||||||
CMD [ "/ha_entrypoint.sh" ]
|
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
|
||||||
############
|
ARG DEBIAN_FRONTEND="noninteractive"
|
||||||
# 5 Labels #
|
|
||||||
############
|
|
||||||
|
|
||||||
ARG BUILD_ARCH
|
ARG BUILD_ARCH
|
||||||
ARG BUILD_DATE
|
ARG BUILD_DATE
|
||||||
ARG BUILD_DESCRIPTION
|
ARG BUILD_DESCRIPTION
|
||||||
@@ -93,28 +16,143 @@ ARG BUILD_NAME
|
|||||||
ARG BUILD_REF
|
ARG BUILD_REF
|
||||||
ARG BUILD_REPOSITORY
|
ARG BUILD_REPOSITORY
|
||||||
ARG BUILD_VERSION
|
ARG BUILD_VERSION
|
||||||
ENV BUILD_VERSION="${BUILD_VERSION}"
|
ARG UPSTREAM_REPOSITORY="P-Adamiec/Free-Games-Claimer-Remaster"
|
||||||
|
ARG UPSTREAM_REF="cca4992354215cef8807b748575af797606627f4"
|
||||||
|
|
||||||
|
ENV S6_CMD_WAIT_FOR_SERVICES="1" \
|
||||||
|
S6_CMD_WAIT_FOR_SERVICES_MAXTIME="0" \
|
||||||
|
S6_SERVICES_GRACETIME="0" \
|
||||||
|
VNC_PORT="5900" \
|
||||||
|
NOVNC_PORT="6080" \
|
||||||
|
WIDTH="1280" \
|
||||||
|
HEIGHT="720" \
|
||||||
|
DEPTH="24" \
|
||||||
|
SHOW="1" \
|
||||||
|
COMMIT="${UPSTREAM_REF}" \
|
||||||
|
BRANCH="main" \
|
||||||
|
NOW="${BUILD_DATE}"
|
||||||
|
|
||||||
|
# Install the dependencies used by Free Games Claimer Remaster. The upstream
|
||||||
|
# Dockerfile supports both amd64 (Google Chrome) and arm64 (Chromium), so the
|
||||||
|
# add-on keeps its existing multi-architecture support.
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dos2unix \
|
||||||
|
gnupg \
|
||||||
|
gzip \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
tar \
|
||||||
|
tini \
|
||||||
|
&& mkdir -p /etc/apt/keyrings \
|
||||||
|
&& curl --proto "=https" --tlsv1.2 -fsSL https://packagecloud.io/dcommander/virtualgl/gpgkey \
|
||||||
|
| gpg --dearmor -o /etc/apt/trusted.gpg.d/VirtualGL.gpg \
|
||||||
|
&& curl --proto "=https" --tlsv1.2 -fsSL https://packagecloud.io/dcommander/turbovnc/gpgkey \
|
||||||
|
| gpg --dearmor -o /etc/apt/trusted.gpg.d/TurboVNC.gpg \
|
||||||
|
&& curl --proto "=https" --tlsv1.2 -fsSL https://raw.githubusercontent.com/VirtualGL/repo/main/VirtualGL.list \
|
||||||
|
> /etc/apt/sources.list.d/VirtualGL.list \
|
||||||
|
&& curl --proto "=https" --tlsv1.2 -fsSL https://raw.githubusercontent.com/TurboVNC/repo/main/TurboVNC.list \
|
||||||
|
> /etc/apt/sources.list.d/TurboVNC.list \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
novnc \
|
||||||
|
ratpoison \
|
||||||
|
turbovnc \
|
||||||
|
virtualgl \
|
||||||
|
websockify \
|
||||||
|
libasound2 \
|
||||||
|
libatk-bridge2.0-0 \
|
||||||
|
libatk1.0-0 \
|
||||||
|
libatspi2.0-0 \
|
||||||
|
libcairo2 \
|
||||||
|
libcups2 \
|
||||||
|
libgbm1 \
|
||||||
|
libnspr4 \
|
||||||
|
libnss3 \
|
||||||
|
libpango-1.0-0 \
|
||||||
|
libxcomposite1 \
|
||||||
|
libxdamage1 \
|
||||||
|
libxfixes3 \
|
||||||
|
libxkbcommon0 \
|
||||||
|
&& if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
|
||||||
|
curl -fsSL https://dl.google.com/linux/linux_signing_key.pub \
|
||||||
|
| gpg --dearmor -o /etc/apt/keyrings/google-chrome.gpg; \
|
||||||
|
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google-chrome.gpg] https://dl.google.com/linux/chrome/deb/ stable main" \
|
||||||
|
> /etc/apt/sources.list.d/google-chrome.list; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y --no-install-recommends google-chrome-stable; \
|
||||||
|
else \
|
||||||
|
apt-get install -y --no-install-recommends chromium; \
|
||||||
|
fi \
|
||||||
|
&& ln -sf /usr/share/novnc/vnc_auto.html /usr/share/novnc/index.html \
|
||||||
|
&& ln -sf /usr/bin/python3 /usr/bin/python \
|
||||||
|
&& apt-get purge -y gnupg \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* /var/cache/* /var/tmp/* /tmp/* /usr/share/doc/*
|
||||||
|
|
||||||
|
# Install a deterministic snapshot of the replacement upstream. Updating the
|
||||||
|
# upstream reference is intentionally explicit so image contents cannot change
|
||||||
|
# without an add-on version bump.
|
||||||
|
WORKDIR /fgc
|
||||||
|
RUN curl --proto "=https" --tlsv1.2 -fsSL \
|
||||||
|
"https://github.com/${UPSTREAM_REPOSITORY}/archive/${UPSTREAM_REF}.tar.gz" \
|
||||||
|
-o /tmp/free-games-claimer-remaster.tar.gz \
|
||||||
|
&& tar -xzf /tmp/free-games-claimer-remaster.tar.gz --strip-components=1 -C /fgc \
|
||||||
|
&& python3 -m pip install --no-cache-dir --break-system-packages -r requirements.txt \
|
||||||
|
&& dos2unix ./*.sh \
|
||||||
|
&& chmod +x ./*.sh \
|
||||||
|
&& cp docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh \
|
||||||
|
&& chmod 0755 /usr/local/bin/docker-entrypoint.sh \
|
||||||
|
&& rm -f /tmp/free-games-claimer-remaster.tar.gz \
|
||||||
|
&& rm -rf /fgc/data \
|
||||||
|
&& ln -s /data /fgc/data
|
||||||
|
|
||||||
|
# Add Home Assistant integration files and shared helper modules.
|
||||||
|
COPY rootfs/ /
|
||||||
|
RUN find /etc/cont-init.d /usr/local/bin -type f -name "*.sh" -exec chmod 0755 {} + \
|
||||||
|
&& chmod 0755 /usr/local/bin/migrate_vogler_data.py
|
||||||
|
|
||||||
|
ARG MODULES="00-banner.sh 01-custom_script.sh"
|
||||||
|
COPY ha_automodules.sh /ha_automodules.sh
|
||||||
|
RUN chmod 0755 /ha_automodules.sh \
|
||||||
|
&& /ha_automodules.sh "${MODULES}" \
|
||||||
|
&& rm /ha_automodules.sh
|
||||||
|
|
||||||
|
ENV PACKAGES=""
|
||||||
|
COPY ha_autoapps.sh /ha_autoapps.sh
|
||||||
|
RUN chmod 0755 /ha_autoapps.sh \
|
||||||
|
&& /ha_autoapps.sh "${PACKAGES}" \
|
||||||
|
&& rm /ha_autoapps.sh
|
||||||
|
|
||||||
|
ENV S6_STAGE2_HOOK="/ha_entrypoint.sh"
|
||||||
|
COPY ha_entrypoint.sh /ha_entrypoint.sh
|
||||||
|
COPY bashio-standalone.sh /usr/local/lib/bashio-standalone.sh
|
||||||
|
RUN chmod 0755 /ha_entrypoint.sh /usr/local/lib/bashio-standalone.sh
|
||||||
|
|
||||||
|
EXPOSE 5900 6080
|
||||||
|
ENTRYPOINT ["/usr/bin/env"]
|
||||||
|
CMD ["/ha_entrypoint.sh"]
|
||||||
|
|
||||||
LABEL \
|
LABEL \
|
||||||
io.hass.name="${BUILD_NAME}" \
|
io.hass.name="${BUILD_NAME}" \
|
||||||
io.hass.description="${BUILD_DESCRIPTION}" \
|
io.hass.description="${BUILD_DESCRIPTION}" \
|
||||||
io.hass.arch="${BUILD_ARCH}" \
|
io.hass.arch="${BUILD_ARCH}" \
|
||||||
io.hass.type="addon" \
|
io.hass.type="addon" \
|
||||||
io.hass.version=${BUILD_VERSION} \
|
io.hass.version="${BUILD_VERSION}" \
|
||||||
maintainer="alexbelgium (https://github.com/alexbelgium)" \
|
maintainer="alexbelgium (https://github.com/alexbelgium)" \
|
||||||
org.opencontainers.image.title="${BUILD_NAME}" \
|
org.opencontainers.image.title="${BUILD_NAME}" \
|
||||||
org.opencontainers.image.description="${BUILD_DESCRIPTION}" \
|
org.opencontainers.image.description="${BUILD_DESCRIPTION}" \
|
||||||
org.opencontainers.image.vendor="Home Assistant Add-ons" \
|
org.opencontainers.image.vendor="Home Assistant Add-ons" \
|
||||||
org.opencontainers.image.authors="alexbelgium (https://github.com/alexbelgium)" \
|
org.opencontainers.image.authors="alexbelgium (https://github.com/alexbelgium)" \
|
||||||
org.opencontainers.image.licenses="MIT" \
|
org.opencontainers.image.licenses="AGPL-3.0" \
|
||||||
org.opencontainers.image.url="https://github.com/alexbelgium" \
|
org.opencontainers.image.url="https://github.com/${BUILD_REPOSITORY}" \
|
||||||
org.opencontainers.image.source="https://github.com/${BUILD_REPOSITORY}" \
|
org.opencontainers.image.source="https://github.com/${BUILD_REPOSITORY}" \
|
||||||
org.opencontainers.image.documentation="https://github.com/${BUILD_REPOSITORY}/blob/main/README.md" \
|
org.opencontainers.image.documentation="https://github.com/${BUILD_REPOSITORY}/blob/master/free_games_claimer/README.md" \
|
||||||
org.opencontainers.image.created=${BUILD_DATE} \
|
org.opencontainers.image.created="${BUILD_DATE}" \
|
||||||
org.opencontainers.image.revision=${BUILD_REF} \
|
org.opencontainers.image.revision="${BUILD_REF}" \
|
||||||
org.opencontainers.image.version=${BUILD_VERSION}
|
org.opencontainers.image.version="${BUILD_VERSION}" \
|
||||||
|
io.hass.upstream="https://github.com/${UPSTREAM_REPOSITORY}/tree/${UPSTREAM_REF}"
|
||||||
####################
|
|
||||||
# 6 HealthcheckNOT #
|
|
||||||
####################
|
|
||||||
|
|
||||||
# Can't be implemented as container is optimized for memory usage, so the webserver and Node are spun down during idle
|
|
||||||
|
|||||||
@@ -1,128 +1,164 @@
|
|||||||
## ⚠ VNC not working on several machines. Please use config.env to execute the script
|
# Home Assistant add-on: Free Games Claimer
|
||||||
|
|
||||||
# Home assistant add-on: Free Games Claimer
|
I maintain this and other Home Assistant add-ons in my free time. Keeping up
|
||||||
|
with upstream changes, Home Assistant changes, and testing on real hardware
|
||||||
|
takes a significant amount of time.
|
||||||
I maintain this and other Home Assistant add-ons in my free time: keeping up with upstream changes, HA changes, and testing on real hardware takes a lot of time (and some money). I use around 5-10 of my >110 addons so regularly I install test machines (and purchase some test services such as vpn) that I don't use myself to troubleshoot and improve the addons
|
|
||||||
|
|
||||||
If this add-on saves you time or makes your setup easier, I would be very grateful for your support!
|
|
||||||
|
|
||||||
[![Buy me a coffee][donation-badge]](https://www.buymeacoffee.com/alexbelgium)
|
[![Buy me a coffee][donation-badge]](https://www.buymeacoffee.com/alexbelgium)
|
||||||
[![Donate via PayPal][paypal-badge]](https://www.paypal.com/donate/?hosted_button_id=DZFULJZTP3UQA)
|
[![Donate via PayPal][paypal-badge]](https://www.paypal.com/donate/?hosted_button_id=DZFULJZTP3UQA)
|
||||||
|
|
||||||
## Addon informations
|
## Add-on information
|
||||||
|
|
||||||

|

|
||||||

|
|
||||||

|

|
||||||
|
|
||||||
[](https://www.codacy.com/gh/alexbelgium/hassio-addons/dashboard?utm_source=github.com&utm_medium=referral&utm_content=alexbelgium/hassio-addons&utm_campaign=Badge_Grade)
|
|
||||||
[](https://github.com/alexbelgium/hassio-addons/actions/workflows/weekly-supelinter.yaml)
|
[](https://github.com/alexbelgium/hassio-addons/actions/workflows/weekly-supelinter.yaml)
|
||||||
[](https://github.com/alexbelgium/hassio-addons/actions/workflows/onpush_builder.yaml)
|
[](https://github.com/alexbelgium/hassio-addons/actions/workflows/onpush_builder.yaml)
|
||||||
|
|
||||||
[donation-badge]: https://img.shields.io/badge/Buy%20me%20a%20coffee-%23d32f2f?logo=buy-me-a-coffee&style=flat&logoColor=white
|
[donation-badge]: https://img.shields.io/badge/Buy%20me%20a%20coffee-%23d32f2f?logo=buy-me-a-coffee&style=flat&logoColor=white
|
||||||
[paypal-badge]: https://img.shields.io/badge/Donate%20via%20PayPal-0070BA?logo=paypal&style=flat&logoColor=white
|
[paypal-badge]: https://img.shields.io/badge/Donate%20via%20PayPal-0070BA?logo=paypal&style=flat&logoColor=white
|
||||||
|
|
||||||
_Thanks to everyone having starred my repo! To star it click on the image below, then it will be on top right. Thanks!_
|
|
||||||
|
|
||||||
[](https://github.com/alexbelgium/hassio-addons/stargazers)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
[Free Games Claimer](https://github.com/vogler/free-games-claimer) : Claims free games periodically on
|
This add-on is based on
|
||||||
|
[Free Games Claimer Remaster](https://github.com/P-Adamiec/Free-Games-Claimer-Remaster).
|
||||||
|
It can claim free games from:
|
||||||
|
|
||||||
- Epic Games Store
|
- Epic Games Store
|
||||||
- Amazon Prime Gaming
|
- Amazon Prime Gaming
|
||||||
- GOG
|
- GOG
|
||||||
- Live Games with Gold - planned
|
- Steam
|
||||||
|
- GamerPower-supported stores, when explicitly enabled
|
||||||
|
|
||||||
This addon is based on the docker image https://github.com/vogler/free-games-claimer
|
For compatibility with previous add-on releases, the default store selection
|
||||||
|
remains Epic Games, Prime Gaming, and GOG.
|
||||||
|
|
||||||
## Configuration
|
## Web interface
|
||||||
|
|
||||||
Webui can be found at <http://homeassistant:6080> (NoVNC interface - currently has issues on some machines).
|
The noVNC interface remains available on port `6080`:
|
||||||
|
|
||||||
### Options
|
```text
|
||||||
|
http://homeassistant:6080
|
||||||
| Option | Type | Default | Description |
|
|
||||||
|--------|------|---------|-------------|
|
|
||||||
| `CMD_ARGUMENTS` | str | `node epic-games ; node prime-gaming ; node gog` | Commands to run for claiming games |
|
|
||||||
| `CONFIG_LOCATION` | str | `/config/config.env` | Location of the configuration file |
|
|
||||||
|
|
||||||
### Example Configuration
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
CMD_ARGUMENTS: "node epic-games ; node prime-gaming ; node gog"
|
|
||||||
CONFIG_LOCATION: "/config/config.env"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Configuration
|
It can be used for initial sign-in, CAPTCHA handling, or other manual browser
|
||||||
|
interaction. Set `VNC_PASSWORD` in `config.env` to protect the VNC session.
|
||||||
|
|
||||||
All main configuration is done via the `config.env` file located at `/config/addons_config/free_games_claimer/config.env`.
|
## Add-on options
|
||||||
|
|
||||||
If this file doesn't exist, it will be created at first boot with default settings.
|
| Option | Default | Description |
|
||||||
|
|--------|---------|-------------|
|
||||||
|
| `CONFIG_LOCATION` | `/config/config.env` | Persistent environment configuration file |
|
||||||
|
| `RUN_ONCE` | `true` | Run all selected claimers once, then stop the add-on as previous releases did |
|
||||||
|
| `STORES` | empty | Optional comma-separated override, such as `epic,prime,gog,steam` |
|
||||||
|
| `CMD_ARGUMENTS` | `node epic-games ; node prime-gaming ; node gog` | Deprecated compatibility option; recognized legacy command names are converted to `STORES` |
|
||||||
|
| `env_vars` | `[]` | Additional environment variables passed to the add-on |
|
||||||
|
|
||||||
### Required Environment Variables
|
### Run modes
|
||||||
|
|
||||||
Add these to your `config.env` file:
|
With `RUN_ONCE: true`, the add-on performs one claiming pass and stops. This is
|
||||||
|
the default and preserves the behavior of the former vogler-based add-on.
|
||||||
|
|
||||||
|
With `RUN_ONCE: false`, the remaster remains running and uses its internal
|
||||||
|
scheduler. Set `SCHEDULER_HOURS` in `config.env` to control the interval.
|
||||||
|
|
||||||
|
## Environment configuration
|
||||||
|
|
||||||
|
The add-on keeps its configuration in `CONFIG_LOCATION`, which defaults to
|
||||||
|
`/config/config.env`. From Home Assistant this is stored in the add-on's
|
||||||
|
private `addon_configs` directory and can be edited with a compatible file
|
||||||
|
browser add-on.
|
||||||
|
|
||||||
|
A template is created on first start. Common examples are:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
# Epic Games Store
|
# Preserve the former default selection
|
||||||
|
STORES=epic,prime,gog
|
||||||
|
|
||||||
|
# Epic Games
|
||||||
EG_EMAIL=your-email@example.com
|
EG_EMAIL=your-email@example.com
|
||||||
EG_PASSWORD=your-password
|
EG_PASSWORD=your-password
|
||||||
|
EG_OTPKEY=
|
||||||
|
|
||||||
# Amazon Prime Gaming
|
# Amazon Prime Gaming
|
||||||
PG_EMAIL=your-amazon-email@example.com
|
PG_EMAIL=your-amazon-email@example.com
|
||||||
PG_PASSWORD=your-amazon-password
|
PG_PASSWORD=your-password
|
||||||
|
PG_OTPKEY=
|
||||||
|
|
||||||
# GOG (optional)
|
# GOG
|
||||||
GOG_EMAIL=your-gog-email@example.com
|
GOG_EMAIL=your-gog-email@example.com
|
||||||
GOG_PASSWORD=your-gog-password
|
GOG_PASSWORD=your-password
|
||||||
|
|
||||||
# Notifications (optional)
|
# Optional Steam support
|
||||||
EMAIL_SMTP_HOST=smtp.gmail.com
|
STEAM_USERNAME=your-steam-username
|
||||||
EMAIL_SMTP_PORT=587
|
STEAM_PASSWORD=your-password
|
||||||
EMAIL_USER=notifications@example.com
|
|
||||||
EMAIL_PASS=your-app-password
|
# Optional notifications
|
||||||
EMAIL_TO=recipient@example.com
|
NOTIFY=tgram://bot-token/chat-id
|
||||||
|
# DISCORD_WEBHOOK=https://discord.com/api/webhooks/...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Additional Options
|
Existing variables such as `EG_EMAIL`, `EG_PASSWORD`, `PG_EMAIL`,
|
||||||
|
`PG_PASSWORD`, `PG_OTPKEY`, `GOG_EMAIL`, `GOG_PASSWORD`, `SHOW`, `WIDTH`,
|
||||||
|
`HEIGHT`, `TIMEOUT`, `LOGIN_TIMEOUT`, `DRYRUN`, and `NOTIFY` remain compatible.
|
||||||
|
See the
|
||||||
|
[upstream configuration reference](https://github.com/P-Adamiec/Free-Games-Claimer-Remaster#configuration)
|
||||||
|
for all available settings.
|
||||||
|
|
||||||
For complete configuration options and advanced settings, see: https://github.com/vogler/free-games-claimer#configuration--options
|
## Upgrade from version 1.8
|
||||||
|
|
||||||
### Important Notes
|
Version 2.0 changes the application engine from
|
||||||
|
`vogler/free-games-claimer` (Node.js, Playwright, and Firefox) to
|
||||||
|
`P-Adamiec/Free-Games-Claimer-Remaster` (Python, nodriver, and Chromium).
|
||||||
|
The add-on performs the following migration automatically on first start:
|
||||||
|
|
||||||
- **VNC Issues**: The NoVNC web interface is currently not working reliably on several machines
|
1. The existing `config.env` remains at the same configured location.
|
||||||
- **Recommended**: Use the `config.env` file for configuration instead of the web interface
|
2. Legacy `epic-games.json`, `prime-gaming.json`, and `gog.json` claim history
|
||||||
- **Security**: Store credentials securely and consider using app-specific passwords where available
|
is imported into the remaster SQLite database at `/data/fgc.db`.
|
||||||
|
3. Existing database rows are detected and are not duplicated if migration is
|
||||||
|
retried.
|
||||||
|
4. A pre-migration database backup is created when an existing `fgc.db` is
|
||||||
|
present.
|
||||||
|
5. All old files remain under `/data/data` for rollback or manual recovery.
|
||||||
|
|
||||||
### Custom Scripts and Environment Variables
|
Browser sessions cannot be converted because the old add-on used a shared
|
||||||
|
Firefox profile while the remaster uses separate Chromium profiles per store.
|
||||||
|
Credentials remain available through `config.env`, but accounts that require
|
||||||
|
interactive authentication may need a one-time login through noVNC after the
|
||||||
|
upgrade. The old Firefox profile is retained and is never deleted.
|
||||||
|
|
||||||
This addon supports custom scripts and environment variables through the `addon_config` mapping:
|
The external noVNC port remains `6080`, although the standalone remaster image
|
||||||
|
normally uses port `7080`.
|
||||||
|
|
||||||
- **Custom scripts**: See [Running Custom Scripts in Addons](https://github.com/alexbelgium/hassio-addons/wiki/Running-custom-scripts-in-Addons)
|
## Upstream update policy
|
||||||
- **env_vars option**: Use the add-on `env_vars` option to pass extra environment variables (uppercase or lowercase names). See https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2 for details.
|
|
||||||
|
The image is built from an explicit upstream commit in the Dockerfile. This
|
||||||
|
keeps amd64 and aarch64 images reproducible and prevents an upstream branch or
|
||||||
|
container tag from changing without an add-on review and version bump.
|
||||||
|
|
||||||
|
The repository updater is intentionally paused for this add-on because the
|
||||||
|
add-on uses its own `2.x` version series while the replacement upstream uses a
|
||||||
|
`1.x` version series. An automatic replacement would risk a Home Assistant
|
||||||
|
version regression and would not safely update the pinned commit. A maintainer
|
||||||
|
upstream update must therefore update `UPSTREAM_REF`, `upstream_version`, the
|
||||||
|
add-on version, and `CHANGELOG.md` together.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The installation of this add-on is pretty straightforward and not different in comparison to installing any other add-on.
|
1. Add this add-on repository to the Home Assistant add-on store.
|
||||||
|
2. Install **Free Games Claimer**.
|
||||||
|
3. Configure the add-on options as needed.
|
||||||
|
4. Start the add-on and review its log.
|
||||||
|
5. Open noVNC if an account needs manual authentication.
|
||||||
|
|
||||||
1. Add my add-ons repository to your home assistant instance (in supervisor addons store at top right, or click button below if you have configured my HA)
|
[](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons)
|
||||||
[](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons)
|
|
||||||
1. Install this add-on.
|
## Custom scripts and environment variables
|
||||||
1. Click the `Save` button to store your configuration.
|
|
||||||
1. Set the add-on options to your preferences
|
- [Running custom scripts in add-ons](https://github.com/alexbelgium/hassio-addons/wiki/Running-custom-scripts-in-Addons)
|
||||||
1. Start the add-on.
|
- [Passing environment variables to an add-on](https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2)
|
||||||
1. Check the logs of the add-on to see if everything went well.
|
|
||||||
1. Open the webUI and adapt the software options
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Create an issue on github
|
Open an issue in the
|
||||||
|
[add-on repository](https://github.com/alexbelgium/hassio-addons/issues).
|
||||||
[repository]: https://github.com/alexbelgium/hassio-addons
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"build_from": {
|
"build_from": {
|
||||||
"aarch64": "ghcr.io/vogler/free-games-claimer:latest",
|
"aarch64": "debian:bookworm-slim",
|
||||||
"amd64": "ghcr.io/vogler/free-games-claimer:latest"
|
"amd64": "debian:bookworm-slim"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
# Free Games Claimer Remaster add-on (pinned source)
|
||||||
arch:
|
arch:
|
||||||
- aarch64
|
- aarch64
|
||||||
- amd64
|
- amd64
|
||||||
description:
|
description: >-
|
||||||
automatically claims free games on the Epic Games Store, Amazon Prime
|
Automatically claims free games from Epic Games Store, Amazon Prime Gaming,
|
||||||
Gaming and GOG
|
GOG, Steam, and optional GamerPower-supported stores.
|
||||||
devices:
|
devices:
|
||||||
- /dev/dri
|
- /dev/dri
|
||||||
- /dev/dri/card0
|
- /dev/dri/card0
|
||||||
@@ -73,25 +74,29 @@ init: false
|
|||||||
map:
|
map:
|
||||||
- addon_config:rw
|
- addon_config:rw
|
||||||
- homeassistant_config:rw
|
- homeassistant_config:rw
|
||||||
name: Free Games Claimer (NoVNC not working)
|
name: Free Games Claimer
|
||||||
options:
|
options:
|
||||||
env_vars: []
|
env_vars: []
|
||||||
CMD_ARGUMENTS: node epic-games ; node prime-gaming ; node gog
|
CMD_ARGUMENTS: node epic-games ; node prime-gaming ; node gog
|
||||||
|
STORES: ""
|
||||||
|
RUN_ONCE: true
|
||||||
CONFIG_LOCATION: /config/config.env
|
CONFIG_LOCATION: /config/config.env
|
||||||
ports:
|
ports:
|
||||||
5900/tcp: null
|
5900/tcp: null
|
||||||
6080/tcp: 6080
|
6080/tcp: 6080
|
||||||
ports_description:
|
ports_description:
|
||||||
5900/tcp: VNC port
|
5900/tcp: VNC port
|
||||||
6080/tcp: NOVNC port
|
6080/tcp: noVNC web interface
|
||||||
schema:
|
schema:
|
||||||
env_vars:
|
env_vars:
|
||||||
- name: match(^[A-Za-z0-9_]+$)
|
- name: match(^[A-Za-z0-9_]+$)
|
||||||
value: str?
|
value: str?
|
||||||
CMD_ARGUMENTS: str
|
CMD_ARGUMENTS: str?
|
||||||
|
STORES: str?
|
||||||
|
RUN_ONCE: bool
|
||||||
CONFIG_LOCATION: str
|
CONFIG_LOCATION: str
|
||||||
slug: free_games_claimer
|
slug: free_games_claimer
|
||||||
udev: true
|
udev: true
|
||||||
url: https://github.com/alexbelgium/hassio-addons
|
url: https://github.com/alexbelgium/hassio-addons
|
||||||
version: "1.8"
|
version: "2.0.0"
|
||||||
webui: "[PROTO:ssl]://[HOST]:[PORT:6080]"
|
webui: "[PROTO:ssl]://[HOST]:[PORT:6080]"
|
||||||
|
|||||||
@@ -1,85 +1,152 @@
|
|||||||
#!/usr/bin/env bashio
|
#!/usr/bin/env bashio
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
set -e
|
set -eo pipefail
|
||||||
|
|
||||||
##############
|
CONFIG_FILE="/config/config.env"
|
||||||
# Initialize #
|
if bashio::config.has_value 'CONFIG_LOCATION'; then
|
||||||
##############
|
CONFIG_FILE="$(bashio::config 'CONFIG_LOCATION')"
|
||||||
|
fi
|
||||||
|
CONFIG_DIR="$(dirname "${CONFIG_FILE}")"
|
||||||
|
RUNTIME_CONFIG="/data/config.env"
|
||||||
|
|
||||||
CONFIG_HOME="$(bashio::config "CONFIG_LOCATION")"
|
mkdir -p "${CONFIG_DIR}" /data
|
||||||
CONFIG_HOME="$(dirname "$CONFIG_HOME")"
|
|
||||||
|
|
||||||
# Use new config file
|
# Recover from an old add-on bug that could create config.env as a directory.
|
||||||
if [ ! -f "$CONFIG_HOME/config.env" ]; then
|
if [ -d "${CONFIG_FILE}" ]; then
|
||||||
# Copy default config.env
|
bashio::log.warning "Found a directory at ${CONFIG_FILE}; replacing it with a configuration file"
|
||||||
cp /templates/config.env "$CONFIG_HOME/"
|
rm -rf "${CONFIG_FILE}"
|
||||||
chmod 755 "$CONFIG_HOME/config.env"
|
fi
|
||||||
bashio::log.warning "A default config.env file was copied to $CONFIG_HOME. Please customize according to https://github.com/vogler/free-games-claimer/tree/main#configuration--options and restart the add-on"
|
|
||||||
|
if [ ! -f "${CONFIG_FILE}" ]; then
|
||||||
|
install -m 0600 /templates/config.env "${CONFIG_FILE}"
|
||||||
|
bashio::log.warning \
|
||||||
|
"Created ${CONFIG_FILE}. Add account credentials there and restart the add-on if automatic login is required."
|
||||||
else
|
else
|
||||||
bashio::log.info "Using existing config.env file in $CONFIG_HOME. Please customize according to https://github.com/vogler/free-games-claimer/tree/main#configuration--options and restart the add-on"
|
bashio::log.info "Using configuration from ${CONFIG_FILE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove erroneous folder named config.env (bug fix for looping issue)
|
# The remaster reads /fgc/data/config.env. /fgc/data is linked to Home
|
||||||
if [ -d "$CONFIG_HOME/config.env" ]; then
|
# Assistant's persistent /data volume by the Dockerfile.
|
||||||
bashio::log.warning "Found directory named config.env, deleting it..."
|
install -m 0600 "${CONFIG_FILE}" "${RUNTIME_CONFIG}"
|
||||||
rm -rf "$CONFIG_HOME/config.env" # Fix: Ensures directory removal even if it exists
|
sed -i 's/\r$//' "${RUNTIME_CONFIG}"
|
||||||
cp /templates/config.env "$CONFIG_HOME/config.env" # Recreate as a valid file
|
|
||||||
chmod 755 "$CONFIG_HOME/config.env"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy new file
|
# Export values needed by the VNC entrypoint as well as by the Python app.
|
||||||
mkdir -p /data/data
|
|
||||||
cp "$CONFIG_HOME/config.env" /data/data/
|
|
||||||
|
|
||||||
# Permissions
|
|
||||||
chmod -R 755 "$CONFIG_HOME"
|
|
||||||
|
|
||||||
# Export variables
|
|
||||||
set -a
|
set -a
|
||||||
echo ""
|
|
||||||
bashio::log.info "Sourcing variables from $CONFIG_HOME/config.env"
|
|
||||||
cp "$CONFIG_HOME"/config.env /config.env
|
|
||||||
# Remove previous instance
|
|
||||||
sed -i "s|export ||g" /config.env
|
|
||||||
# Add export for non empty lines
|
|
||||||
sed -i '/\S/s/^/export /' /config.env
|
|
||||||
# Delete lines starting with #
|
|
||||||
sed -i '/export #/d' /config.env
|
|
||||||
# Get variables
|
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
source /config.env
|
source "${RUNTIME_CONFIG}"
|
||||||
rm /config.env
|
|
||||||
set +a
|
set +a
|
||||||
|
|
||||||
##############
|
# The Home Assistant port mapping is intentionally kept at 6080 for a seamless
|
||||||
# Launch App #
|
# upgrade from the previous add-on, even though the new upstream defaults to 7080.
|
||||||
##############
|
if [ -n "${NOVNC_PORT:-}" ] && [ "${NOVNC_PORT}" != "6080" ]; then
|
||||||
|
bashio::log.warning "NOVNC_PORT=${NOVNC_PORT} is not supported by the add-on port mapping; using 6080"
|
||||||
|
fi
|
||||||
|
export NOVNC_PORT="6080"
|
||||||
|
export VNC_PORT="5900"
|
||||||
|
|
||||||
# Go to folder
|
# Absolute paths from the former image pointed to its Firefox profile. The
|
||||||
cd /data || true
|
# replacement uses Chromium profiles and must start with a separate directory.
|
||||||
|
if [ "${BROWSER_DIR:-}" = "/data/data/browser" ]; then
|
||||||
|
bashio::log.warning "Remapping legacy Firefox BROWSER_DIR to the remaster Chromium profile directory"
|
||||||
|
export BROWSER_DIR="data/browser"
|
||||||
|
fi
|
||||||
|
if [ "${SCREENSHOTS_DIR:-}" = "/data/data/screenshots" ]; then
|
||||||
|
export SCREENSHOTS_DIR="/fgc/data/screenshots"
|
||||||
|
fi
|
||||||
|
|
||||||
# Fetch commands
|
append_store() {
|
||||||
CMD_ARGUMENTS="$(bashio::config "CMD_ARGUMENTS")"
|
local store="${1}"
|
||||||
IFS=';'
|
local current="${2}"
|
||||||
read -ar strarr <<< "$CMD_ARGUMENTS"
|
|
||||||
|
|
||||||
# Sanitizes commands
|
if [[ ",${current}," == *",${store},"* ]]; then
|
||||||
trim() {
|
printf '%s' "${current}"
|
||||||
local var="$*"
|
elif [ -n "${current}" ]; then
|
||||||
var="${var#"${var%%[![:space:]]*}"}"
|
printf '%s,%s' "${current}" "${store}"
|
||||||
var="${var%"${var##*[![:space:]]}"}"
|
else
|
||||||
printf '%s' "$var"
|
printf '%s' "${store}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add docker-entrypoint command
|
legacy_commands_to_stores() {
|
||||||
for val in "${strarr[@]}"; do
|
local commands="${1}"
|
||||||
val="$(trim "$val")"
|
local selected=""
|
||||||
echo " "
|
local command=""
|
||||||
bashio::log.info "Starting the app with arguments \"$val\""
|
local normalized=""
|
||||||
echo " "
|
local command_list=()
|
||||||
echo "$val" | xargs docker-entrypoint.sh || true
|
|
||||||
done
|
|
||||||
|
|
||||||
bashio::log.info "All actions concluded. Stopping in 10 seconds."
|
IFS=';' read -ra command_list <<< "${commands}"
|
||||||
sleep 10
|
for command in "${command_list[@]}"; do
|
||||||
bashio::addon.stop
|
normalized="${command,,}"
|
||||||
|
case "${normalized}" in
|
||||||
|
*epic-games*|*epicgames*|*" epic"*|epic*)
|
||||||
|
selected="$(append_store "epic" "${selected}")"
|
||||||
|
;;
|
||||||
|
*prime-gaming*|*primegaming*|*" prime"*|prime*|*" amazon"*|amazon*)
|
||||||
|
selected="$(append_store "prime" "${selected}")"
|
||||||
|
;;
|
||||||
|
*steam-games*|*" steam"*|steam*)
|
||||||
|
selected="$(append_store "steam" "${selected}")"
|
||||||
|
;;
|
||||||
|
*gamerpower*)
|
||||||
|
selected="$(append_store "gamerpower" "${selected}")"
|
||||||
|
;;
|
||||||
|
*" gog"*|gog*)
|
||||||
|
selected="$(append_store "gog" "${selected}")"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '%s' "${selected}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# A non-empty STORES add-on option takes priority. Otherwise retain a STORES
|
||||||
|
# value from config.env, then fall back to translating the legacy commands.
|
||||||
|
STORES_OPTION=""
|
||||||
|
if bashio::config.has_value 'STORES'; then
|
||||||
|
STORES_OPTION="$(bashio::config 'STORES')"
|
||||||
|
fi
|
||||||
|
if [ -n "${STORES_OPTION}" ]; then
|
||||||
|
export STORES="${STORES_OPTION}"
|
||||||
|
elif [ -z "${STORES:-}" ]; then
|
||||||
|
CMD_ARGUMENTS=""
|
||||||
|
if bashio::config.has_value 'CMD_ARGUMENTS'; then
|
||||||
|
CMD_ARGUMENTS="$(bashio::config 'CMD_ARGUMENTS')"
|
||||||
|
fi
|
||||||
|
STORES="$(legacy_commands_to_stores "${CMD_ARGUMENTS}")"
|
||||||
|
export STORES="${STORES:-epic,prime,gog}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
bashio::log.info "Enabled stores: ${STORES:-epic,prime,gog}"
|
||||||
|
|
||||||
|
# Import claim history from vogler/free-games-claimer once. Legacy files and
|
||||||
|
# browser data are retained under /data/data for rollback and manual recovery.
|
||||||
|
/usr/local/bin/migrate_vogler_data.py
|
||||||
|
|
||||||
|
APP_COMMAND=(python3 /fgc/main.py)
|
||||||
|
RUN_ONCE="true"
|
||||||
|
if bashio::config.has_value 'RUN_ONCE' && ! bashio::config.true 'RUN_ONCE'; then
|
||||||
|
RUN_ONCE="false"
|
||||||
|
fi
|
||||||
|
if [ "${RUN_ONCE}" = "true" ]; then
|
||||||
|
APP_COMMAND+=(--once)
|
||||||
|
bashio::log.info "Starting a single claiming run (legacy-compatible mode)"
|
||||||
|
|
||||||
|
set +e
|
||||||
|
/usr/local/bin/docker-entrypoint.sh "${APP_COMMAND[@]}"
|
||||||
|
exit_code=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "${exit_code}" -ne 0 ]; then
|
||||||
|
bashio::log.error "Free Games Claimer exited with status ${exit_code}"
|
||||||
|
else
|
||||||
|
bashio::log.info "Claiming run completed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
bashio::log.info "Stopping the add-on"
|
||||||
|
sleep 2
|
||||||
|
bashio::addon.stop
|
||||||
|
exit "${exit_code}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
bashio::log.info "Starting the built-in scheduler"
|
||||||
|
exec /usr/local/bin/docker-entrypoint.sh "${APP_COMMAND[@]}"
|
||||||
|
|||||||
@@ -1,7 +1,39 @@
|
|||||||
HEIGHT=1280
|
# Free Games Claimer Remaster configuration
|
||||||
LOGIN_TIMEOUT=180
|
# Complete option reference:
|
||||||
NOTIFY_TITLE='Free Games Claimer'
|
# https://github.com/P-Adamiec/Free-Games-Claimer-Remaster#configuration
|
||||||
# List of environment variables, see : https://github.com/vogler/free-games-claimer#configuration--options
|
|
||||||
|
# Browser and noVNC
|
||||||
SHOW=1
|
SHOW=1
|
||||||
TIMEOUT=60
|
|
||||||
WIDTH=1280
|
WIDTH=1280
|
||||||
|
HEIGHT=720
|
||||||
|
TIMEOUT=60
|
||||||
|
LOGIN_TIMEOUT=180
|
||||||
|
VNC_LOGIN_TIMEOUT=180
|
||||||
|
NOVNC_PORT=6080
|
||||||
|
|
||||||
|
# Keep the previous add-on's default stores. Add steam or gamerpower if wanted.
|
||||||
|
STORES=epic,prime,gog
|
||||||
|
|
||||||
|
# Used only when RUN_ONCE is disabled in the add-on options.
|
||||||
|
SCHEDULER_HOURS=12
|
||||||
|
|
||||||
|
# Common credentials can be used as fallbacks for all stores.
|
||||||
|
# EMAIL=
|
||||||
|
# PASSWORD=
|
||||||
|
|
||||||
|
# Store-specific credentials take priority over EMAIL/PASSWORD.
|
||||||
|
# EG_EMAIL=
|
||||||
|
# EG_PASSWORD=
|
||||||
|
# EG_OTPKEY=
|
||||||
|
# EG_PARENTALPIN=
|
||||||
|
# PG_EMAIL=
|
||||||
|
# PG_PASSWORD=
|
||||||
|
# PG_OTPKEY=
|
||||||
|
# GOG_EMAIL=
|
||||||
|
# GOG_PASSWORD=
|
||||||
|
# STEAM_USERNAME=
|
||||||
|
# STEAM_PASSWORD=
|
||||||
|
|
||||||
|
# Notifications (Apprise or Discord)
|
||||||
|
# NOTIFY=
|
||||||
|
# DISCORD_WEBHOOK=
|
||||||
|
|||||||
248
free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py
Normal file
248
free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Migrate legacy vogler/free-games-claimer JSON history to the remaster DB."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sqlite3
|
||||||
|
import sys
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Iterator
|
||||||
|
|
||||||
|
DATA_DIR = Path(os.environ.get("FGC_DATA_DIR", "/data"))
|
||||||
|
LEGACY_DIR = DATA_DIR / "data"
|
||||||
|
DATABASE = DATA_DIR / "fgc.db"
|
||||||
|
MARKER = DATA_DIR / ".vogler-remaster-migrated-v1.json"
|
||||||
|
BACKUP = DATA_DIR / "fgc.db.pre-vogler-migration"
|
||||||
|
|
||||||
|
SOURCES = {
|
||||||
|
"epic": "epic-games.json",
|
||||||
|
"prime": "prime-gaming.json",
|
||||||
|
"gog": "gog.json",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def log(message: str) -> None:
|
||||||
|
print(f"[legacy migration] {message}", flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
def locate_source(filename: str) -> Path | None:
|
||||||
|
"""Prefer the old nested data directory, with a root fallback."""
|
||||||
|
for candidate in (LEGACY_DIR / filename, DATA_DIR / filename):
|
||||||
|
if candidate.is_file():
|
||||||
|
return candidate
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_timestamp(value: Any) -> str:
|
||||||
|
if isinstance(value, str) and value.strip():
|
||||||
|
raw = value.strip().replace("Z", "+00:00")
|
||||||
|
try:
|
||||||
|
parsed = datetime.fromisoformat(raw)
|
||||||
|
if parsed.tzinfo is not None:
|
||||||
|
parsed = parsed.astimezone(timezone.utc).replace(tzinfo=None)
|
||||||
|
return parsed.isoformat(sep=" ", timespec="seconds")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return datetime.now(timezone.utc).replace(tzinfo=None).isoformat(
|
||||||
|
sep=" ", timespec="seconds"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def clean(value: Any, *, default: str = "", limit: int | None = None) -> str:
|
||||||
|
result = default if value is None else str(value)
|
||||||
|
if limit is not None:
|
||||||
|
result = result[:limit]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def iter_records(store: str, payload: Any, source: Path) -> Iterator[dict[str, Any]]:
|
||||||
|
if not isinstance(payload, dict):
|
||||||
|
raise ValueError(f"{source} does not contain a JSON object")
|
||||||
|
|
||||||
|
for user, games in payload.items():
|
||||||
|
if not isinstance(games, dict):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for legacy_id, value in games.items():
|
||||||
|
record = value if isinstance(value, dict) else {}
|
||||||
|
title = clean(record.get("title"), default=clean(legacy_id), limit=512)
|
||||||
|
game_id = clean(legacy_id, default=title, limit=256)
|
||||||
|
if not game_id:
|
||||||
|
game_id = title[:256] or "unknown"
|
||||||
|
|
||||||
|
legacy_store = record.get("store")
|
||||||
|
extra = {
|
||||||
|
"migration_source": str(source),
|
||||||
|
"legacy_store": legacy_store,
|
||||||
|
"legacy_time": record.get("time") or record.get("timestamp"),
|
||||||
|
}
|
||||||
|
extra = {key: val for key, val in extra.items() if val not in (None, "")}
|
||||||
|
|
||||||
|
yield {
|
||||||
|
"store": store,
|
||||||
|
"user": clean(user, default="unknown", limit=128) or "unknown",
|
||||||
|
"game_id": game_id,
|
||||||
|
"title": title or game_id,
|
||||||
|
"url": clean(record.get("url"), limit=None) or None,
|
||||||
|
"status": clean(record.get("status"), default="unknown", limit=64)
|
||||||
|
or "unknown",
|
||||||
|
"code": clean(record.get("code"), limit=128) or None,
|
||||||
|
"extra": json.dumps(extra, ensure_ascii=False) if extra else None,
|
||||||
|
"created_at": normalize_timestamp(
|
||||||
|
record.get("time") or record.get("timestamp")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_schema(connection: sqlite3.Connection) -> None:
|
||||||
|
connection.executescript(
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS claimed_games (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
store VARCHAR(32) NOT NULL,
|
||||||
|
user VARCHAR(128) NOT NULL,
|
||||||
|
game_id VARCHAR(256) NOT NULL,
|
||||||
|
title VARCHAR(512) NOT NULL,
|
||||||
|
url TEXT,
|
||||||
|
status VARCHAR(64) NOT NULL DEFAULT 'unknown',
|
||||||
|
code VARCHAR(128),
|
||||||
|
extra TEXT,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_claimed_games_store ON claimed_games (store);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_claimed_games_user ON claimed_games (user);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_claimed_games_game_id ON claimed_games (game_id);
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def migrate() -> int:
|
||||||
|
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
if MARKER.exists():
|
||||||
|
log("Legacy claim history was already migrated")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
sources = {
|
||||||
|
store: source
|
||||||
|
for store, filename in SOURCES.items()
|
||||||
|
if (source := locate_source(filename)) is not None
|
||||||
|
}
|
||||||
|
legacy_browser = LEGACY_DIR / "browser"
|
||||||
|
|
||||||
|
if not sources:
|
||||||
|
if legacy_browser.exists():
|
||||||
|
log(
|
||||||
|
"Legacy Firefox browser data was found but cannot be converted to "
|
||||||
|
"the remaster Chromium profile; a one-time login may be required"
|
||||||
|
)
|
||||||
|
MARKER.write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"migrated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"imported": 0,
|
||||||
|
"sources": [],
|
||||||
|
},
|
||||||
|
indent=2,
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
log("No legacy claim-history files were found")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if DATABASE.exists() and not BACKUP.exists():
|
||||||
|
shutil.copy2(DATABASE, BACKUP)
|
||||||
|
log(f"Backed up the existing database to {BACKUP}")
|
||||||
|
|
||||||
|
imported = 0
|
||||||
|
skipped = 0
|
||||||
|
errors: list[str] = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(DATABASE) as connection:
|
||||||
|
ensure_schema(connection)
|
||||||
|
|
||||||
|
for store, source in sources.items():
|
||||||
|
try:
|
||||||
|
payload = json.loads(source.read_text(encoding="utf-8"))
|
||||||
|
source_imported = 0
|
||||||
|
for record in iter_records(store, payload, source):
|
||||||
|
exists = connection.execute(
|
||||||
|
"""
|
||||||
|
SELECT 1 FROM claimed_games
|
||||||
|
WHERE store = ? AND user = ? AND game_id = ?
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(record["store"], record["user"], record["game_id"]),
|
||||||
|
).fetchone()
|
||||||
|
if exists:
|
||||||
|
skipped += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
connection.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO claimed_games (
|
||||||
|
store, user, game_id, title, url, status, code,
|
||||||
|
extra, created_at, updated_at
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
record["store"],
|
||||||
|
record["user"],
|
||||||
|
record["game_id"],
|
||||||
|
record["title"],
|
||||||
|
record["url"],
|
||||||
|
record["status"],
|
||||||
|
record["code"],
|
||||||
|
record["extra"],
|
||||||
|
record["created_at"],
|
||||||
|
record["created_at"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
imported += 1
|
||||||
|
source_imported += 1
|
||||||
|
|
||||||
|
connection.commit()
|
||||||
|
log(f"Imported {source_imported} record(s) from {source}")
|
||||||
|
except (OSError, ValueError, json.JSONDecodeError, sqlite3.Error) as err:
|
||||||
|
connection.rollback()
|
||||||
|
message = f"Failed to import {source}: {err}"
|
||||||
|
errors.append(message)
|
||||||
|
log(message)
|
||||||
|
except sqlite3.Error as err:
|
||||||
|
log(f"Database migration failed: {err}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if legacy_browser.exists():
|
||||||
|
log(
|
||||||
|
"Legacy Firefox browser data remains in /data/data/browser. It is "
|
||||||
|
"not compatible with Chromium, so use noVNC for a one-time login if needed."
|
||||||
|
)
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
log("Migration was incomplete and will be retried on the next start")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
MARKER.write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"migrated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"imported": imported,
|
||||||
|
"skipped_existing": skipped,
|
||||||
|
"sources": [str(path) for path in sources.values()],
|
||||||
|
},
|
||||||
|
indent=2,
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
log(f"Migration complete: {imported} imported, {skipped} already present")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(migrate())
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"dockerhub_by_date": true,
|
"dockerhub_by_date": false,
|
||||||
"dockerhub_list_size": 2,
|
"dockerhub_list_size": 2,
|
||||||
"last_update": "17-05-2025",
|
"last_update": "17-07-2026",
|
||||||
|
"paused": true,
|
||||||
"repository": "alexbelgium/hassio-addons",
|
"repository": "alexbelgium/hassio-addons",
|
||||||
"slug": "free_games_claimer",
|
"slug": "free_games_claimer",
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"upstream_repo": "vogler/free-games-claimer",
|
"upstream_repo": "P-Adamiec/Free-Games-Claimer-Remaster",
|
||||||
"upstream_version": "1.8"
|
"upstream_version": "1.1"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user