Modernize and upgrade application (#1540)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
Alex Naidis
2025-08-25 04:55:06 +02:00
committed by GitHub
parent 3e51ac1188
commit ff74b50b60
11 changed files with 69 additions and 46 deletions

View File

@@ -11,7 +11,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- -
name: Auto Tag name: Auto Tag
uses: Klemensas/action-autotag@stable uses: Klemensas/action-autotag@stable

View File

@@ -3,7 +3,7 @@ name: release-docker
on: on:
push: push:
tags: tags:
- 'v*.*.*' - "v*.*.*"
pull_request: pull_request:
branches: branches:
- master - master
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
build-docker-images: build-docker-images:
if: ${{ !github.event.pull_request.head.repo.fork }} if: ${{ !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -3,15 +3,15 @@ name: release
on: on:
push: push:
tags: tags:
- 'v*.*.*' - "v*.*.*"
jobs: jobs:
create-release: create-release:
name: Create release name: Create release
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 # get all commits, branches and tags (required for the changelog) fetch-depth: 0 # get all commits, branches and tags (required for the changelog)
@@ -39,27 +39,27 @@ jobs:
build-linux-package: build-linux-package:
name: Build Linux binary name: Build Linux binary
needs: create-release needs: create-release
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 # get all commits, branches and tags (required for the changelog) fetch-depth: 0 # get all commits, branches and tags (required for the changelog)
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: "3.13"
- name: Build artifacts - name: Build artifacts
run: | run: |
python -m pip install -r requirements.txt python -m pip install -r requirements.txt
python -m pip install pyinstaller==5.13.0 python -m pip install pyinstaller==6.14.2
cd src cd src
python build_package.py python build_package.py
- name: Upload release artifacts - name: Upload release artifacts
uses: alexellis/upload-assets@0.4.0 uses: alexellis/upload-assets@0.4.1
env: env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }} GITHUB_TOKEN: ${{ secrets.GH_PAT }}
with: with:
@@ -71,24 +71,24 @@ jobs:
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 # get all commits, branches and tags (required for the changelog) fetch-depth: 0 # get all commits, branches and tags (required for the changelog)
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: "3.13"
- name: Build artifacts - name: Build artifacts
run: | run: |
python -m pip install -r requirements.txt python -m pip install -r requirements.txt
python -m pip install pyinstaller==5.13.0 python -m pip install pyinstaller==6.14.2
cd src cd src
python build_package.py python build_package.py
- name: Upload release artifacts - name: Upload release artifacts
uses: alexellis/upload-assets@0.4.0 uses: alexellis/upload-assets@0.4.1
env: env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }} GITHUB_TOKEN: ${{ secrets.GH_PAT }}
with: with:

View File

@@ -1,4 +1,4 @@
FROM python:3.11-slim-bookworm as builder FROM python:3.13-slim-bookworm as builder
# Build dummy packages to skip installing them and their dependencies # Build dummy packages to skip installing them and their dependencies
RUN apt-get update \ RUN apt-get update \
@@ -12,7 +12,7 @@ RUN apt-get update \
&& equivs-build adwaita-icon-theme \ && equivs-build adwaita-icon-theme \
&& mv adwaita-icon-theme_*.deb /adwaita-icon-theme.deb && mv adwaita-icon-theme_*.deb /adwaita-icon-theme.deb
FROM python:3.11-slim-bookworm FROM python:3.13-slim-bookworm
# Copy dummy packages # Copy dummy packages
COPY --from=builder /*.deb / COPY --from=builder /*.deb /

View File

@@ -59,7 +59,7 @@ docker run -d \
ghcr.io/flaresolverr/flaresolverr:latest ghcr.io/flaresolverr/flaresolverr:latest
``` ```
If your host OS is Debian, make sure `libseccomp2` version is 2.5.x. You can check the version with `sudo apt-cache policy libseccomp2` If your host OS is Debian, make sure `libseccomp2` version is 2.5.x. You can check the version with `sudo apt-cache policy libseccomp2`
and update the package with `sudo apt install libseccomp2=2.5.1-1~bpo10+1` or `sudo apt install libseccomp2=2.5.1-1+deb11u1`. and update the package with `sudo apt install libseccomp2=2.5.1-1~bpo10+1` or `sudo apt install libseccomp2=2.5.1-1+deb11u1`.
Remember to restart the Docker daemon and the container after the update. Remember to restart the Docker daemon and the container after the update.
@@ -77,7 +77,7 @@ This is the recommended way for Windows users.
> **Warning** > **Warning**
> Installing from source code only works for x64 architecture. For other architectures see Docker images. > Installing from source code only works for x64 architecture. For other architectures see Docker images.
* Install [Python 3.11](https://www.python.org/downloads/). * Install [Python 3.13](https://www.python.org/downloads/).
* Install [Chrome](https://www.google.com/intl/en_us/chrome/) (all OS) or [Chromium](https://www.chromium.org/getting-involved/download-chromium/) (just Linux, it doesn't work in Windows) web browser. * Install [Chrome](https://www.google.com/intl/en_us/chrome/) (all OS) or [Chromium](https://www.chromium.org/getting-involved/download-chromium/) (just Linux, it doesn't work in Windows) web browser.
* (Only in Linux) Install [Xvfb](https://en.wikipedia.org/wiki/Xvfb) package. * (Only in Linux) Install [Xvfb](https://en.wikipedia.org/wiki/Xvfb) package.
* (Only in macOS) Install [XQuartz](https://www.xquartz.org/) package. * (Only in macOS) Install [XQuartz](https://www.xquartz.org/) package.
@@ -87,10 +87,10 @@ This is the recommended way for Windows users.
### From source code (FreeBSD/TrueNAS CORE) ### From source code (FreeBSD/TrueNAS CORE)
* Run `pkg install chromium python311 py311-pip xorg-vfbserver` command to install the required dependencies. * Run `pkg install chromium python313 py313-pip xorg-vfbserver` command to install the required dependencies.
* Clone this repository and open a shell in that path. * Clone this repository and open a shell in that path.
* Run `python3.11 -m pip install -r requirements.txt` command to install FlareSolverr dependencies. * Run `python3.13 -m pip install -r requirements.txt` command to install FlareSolverr dependencies.
* Run `python3.11 src/flaresolverr.py` command to start FlareSolverr. * Run `python3.13 src/flaresolverr.py` command to start FlareSolverr.
### Systemd service ### Systemd service

View File

@@ -1,13 +1,14 @@
bottle==0.12.25 bottle==0.13.4
waitress==3.0.1 waitress==3.0.2
selenium==4.15.2 selenium==4.34.2
func-timeout==4.3.5 func-timeout==4.3.5
prometheus-client==0.17.1 prometheus-client==0.22.1
# required by undetected_chromedriver # required by undetected_chromedriver
requests==2.32.4 requests==2.32.4
certifi==2024.07.04 certifi==2025.7.9
websockets==11.0.3 websockets==15.0.1
packaging==25.0
# only required for linux and macos # only required for linux and macos
xvfbwrapper==0.2.9; platform_system != "Windows" xvfbwrapper==0.2.13; platform_system != "Windows"
# only required for windows # only required for windows
pefile==2023.2.7; platform_system == "Windows" pefile==2024.8.26; platform_system == "Windows"

View File

@@ -25,7 +25,7 @@ def clean_files():
def download_chromium(): def download_chromium():
# https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/ # https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/
revision = "1453032" if os.name == 'nt' else '1453031' revision = "1465706" if os.name == 'nt' else '1465706'
arch = 'Win_x64' if os.name == 'nt' else 'Linux_x64' arch = 'Win_x64' if os.name == 'nt' else 'Linux_x64'
dl_file = 'chrome-win' if os.name == 'nt' else 'chrome-linux' dl_file = 'chrome-win' if os.name == 'nt' else 'chrome-linux'
dl_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, 'dist_chrome') dl_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, 'dist_chrome')

View File

@@ -471,7 +471,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
self.patcher.executable_path self.patcher.executable_path
) )
super(Chrome, self).__init__( super().__init__(
service=service, service=service,
options=options, options=options,
keep_alive=keep_alive, keep_alive=keep_alive,
@@ -727,10 +727,8 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
def start_session(self, capabilities=None, browser_profile=None): def start_session(self, capabilities=None, browser_profile=None):
if not capabilities: if not capabilities:
capabilities = self.options.to_capabilities() capabilities = self.options.to_capabilities()
super(selenium.webdriver.chrome.webdriver.WebDriver, self).start_session( super().start_session(capabilities)
capabilities # super(Chrome, self).start_session(capabilities, browser_profile) # Original explicit call commented out
)
# super(Chrome, self).start_session(capabilities, browser_profile)
def find_elements_recursive(self, by, value): def find_elements_recursive(self, by, value):
""" """

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# this module is part of undetected_chromedriver # this module is part of undetected_chromedriver
from distutils.version import LooseVersion from packaging.version import Version as LooseVersion
import io import io
import json import json
import logging import logging
@@ -12,6 +12,7 @@ import random
import re import re
import shutil import shutil
import string import string
import subprocess
import sys import sys
import time import time
from urllib.request import urlopen from urllib.request import urlopen
@@ -222,7 +223,7 @@ class Patcher(object):
pass pass
release = self.fetch_release_number() release = self.fetch_release_number()
self.version_main = release.version[0] self.version_main = release.major
self.version_full = release self.version_full = release
self.unzip_package(self.fetch_package()) self.unzip_package(self.fetch_package())
@@ -327,11 +328,11 @@ class Patcher(object):
""" """
zip_name = f"chromedriver_{self.platform_name}.zip" zip_name = f"chromedriver_{self.platform_name}.zip"
if self.is_old_chromedriver: if self.is_old_chromedriver:
download_url = "%s/%s/%s" % (self.url_repo, self.version_full.vstring, zip_name) download_url = "%s/%s/%s" % (self.url_repo, str(self.version_full), zip_name)
else: else:
zip_name = zip_name.replace("_", "-", 1) zip_name = zip_name.replace("_", "-", 1)
download_url = "https://storage.googleapis.com/chrome-for-testing-public/%s/%s/%s" download_url = "https://storage.googleapis.com/chrome-for-testing-public/%s/%s/%s"
download_url %= (self.version_full.vstring, self.platform_name, zip_name) download_url %= (str(self.version_full), self.platform_name, zip_name)
logger.debug("downloading from %s" % download_url) logger.debug("downloading from %s" % download_url)
return urlretrieve(download_url)[0] return urlretrieve(download_url)[0]
@@ -373,10 +374,31 @@ class Patcher(object):
""" """
exe_name = os.path.basename(exe_name) exe_name = os.path.basename(exe_name)
if IS_POSIX: if IS_POSIX:
r = os.system("kill -f -9 $(pidof %s)" % exe_name) # Using shell=True for pidof, consider a more robust pid finding method if issues arise.
# pgrep can be an alternative: ["pgrep", "-f", exe_name]
# Or psutil if adding a dependency is acceptable.
command = f"pidof {exe_name}"
try:
result = subprocess.run(command, shell=True, capture_output=True, text=True, check=True)
pids = result.stdout.strip().split()
if pids:
subprocess.run(["kill", "-9"] + pids, check=False) # Changed from -f -9 to -9 as -f is not standard for kill
return True
return False # No PIDs found
except subprocess.CalledProcessError: # pidof returns 1 if no process found
return False # No process found
except Exception as e:
logger.debug(f"Error killing process on POSIX: {e}")
return False
else: else:
r = os.system("taskkill /f /im %s" % exe_name) try:
return not r # TASKKILL /F /IM chromedriver.exe
result = subprocess.run(["taskkill", "/f", "/im", exe_name], check=False, capture_output=True)
# taskkill returns 0 if process was killed, 128 if not found.
return result.returncode == 0
except Exception as e:
logger.debug(f"Error killing process on Windows: {e}")
return False
@staticmethod @staticmethod
def gen_random_cdc(): def gen_random_cdc():

View File

@@ -194,6 +194,8 @@ def get_webdriver(proxy: dict = None) -> WebDriver:
windows_headless=windows_headless, headless=get_config_headless()) windows_headless=windows_headless, headless=get_config_headless())
except Exception as e: except Exception as e:
logging.error("Error starting Chrome: %s" % e) logging.error("Error starting Chrome: %s" % e)
# No point in continuing if we cannot retrieve the driver
raise e
# save the patched driver to avoid re-downloads # save the patched driver to avoid re-downloads
if driver_exe_path is None: if driver_exe_path is None:

View File

@@ -1 +1 @@
WebTest==3.0.0 WebTest==3.0.6