Compare commits

...

7 Commits

Author SHA1 Message Date
Simon 6c1d57a654
simplify deployment 2024-02-20 14:28:20 +01:00
Simon 14263c8aa4
bump requirements 2024-02-20 14:20:20 +01:00
Simon d8f54da49b
fix soup parser 2024-02-20 14:19:57 +01:00
Simon 046603b897
fix linter 2024-02-20 14:01:34 +01:00
Simon 2d6ad2c504
fix chrome extension url redirect 2024-02-20 13:56:39 +01:00
Simon 13983f4258
remove version_check 2024-02-20 13:29:10 +01:00
Simon f1f5a0b582
ignore python dep 2024-02-20 13:28:47 +01:00
7 changed files with 38 additions and 143 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
.vscode
.venv
.mypy_cache
__pycache__
# testing logos

View File

@ -1,5 +1,5 @@
# build requirements
FROM python:3.10.8-slim-bullseye AS builder
FROM python:3.11.7-slim-bookworm AS builder
RUN apt-get -y update && \
apt-get -y install --no-install-recommends \
@ -11,7 +11,7 @@ RUN pip install --upgrade pip && pip install --user -r requirements.txt
# load in main image
FROM python:3.10.8-slim-bullseye as tilefy
FROM python:3.11.7-slim-bookworm as tilefy
ARG INSTALL_DEBUG
ENV PYTHONUNBUFFERED 1

View File

@ -9,6 +9,8 @@ function rebuild_test {
rsync -a --progress --delete-after \
--exclude ".git" \
--exclude ".gitignore" \
--exclude ".mypy_cache" \
--exclude ".venv" \
--exclude "**/cache" \
--exclude "**/__pycache__/" \
--exclude "db.sqlite3" \
@ -36,12 +38,12 @@ function validate {
echo "running black"
black --diff --color --check -l 79 "$check_path"
echo "running codespell"
codespell --skip="./.git" "$check_path"
codespell --skip="./.git,./.venv,./.mypy_cache" "$check_path"
echo "running flake8"
flake8 "$check_path" --count --max-complexity=10 --max-line-length=79 \
--show-source --statistics
--show-source --statistics --exclude ".venv"
echo "running isort"
isort --check-only --diff --profile black -l 79 "$check_path"
isort --skip ".venv" --check-only --diff --profile black -l 79 "$check_path"
printf " \n> all validations passed\n"
}
@ -67,10 +69,8 @@ function docker_publish {
echo "build and push $VERSION?"
read -rn 1
# multiarch fix
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# start build
sudo docker buildx build \
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t bbilly1/tilefy \
-t bbilly1/tilefy:"$VERSION" --push .
@ -92,8 +92,8 @@ function sync_unstable {
fi
# start amd64 build
sudo docker buildx build \
--platform linux/amd64 \
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t bbilly1/tilefy:unstable --push .
}
@ -102,8 +102,6 @@ function sync_unstable {
if [[ $1 == "test" ]]; then
rebuild_test
elif [[ $1 == "validate" ]]; then
# check package versions in requirements.txt for updates
python version_check.py
validate "$2"
elif [[ $1 == "docker" ]]; then
docker_publish

View File

@ -1,8 +1,8 @@
APScheduler==3.9.1.post1
beautifulsoup4==4.11.1
flask==2.2.2
Pillow==9.3.0
PyYAML==6.0
redis==4.3.5
requests==2.28.1
uwsgi==2.0.21
APScheduler==3.10.4
beautifulsoup4==4.12.3
flask==3.0.2
Pillow==10.2.0
PyYAML==6.0.1
redis==5.0.1
requests==2.31.0
uwsgi==2.0.24

View File

@ -68,7 +68,7 @@ class Api:
return response
def plugin(self):
"""make request with pugin"""
"""make request with plugin"""
plugin_name = self.tile_config["plugin"]["name"]
item_id = self.tile_config["plugin"]["id"]
if plugin_name == "chrome-extension-users":

View File

@ -9,30 +9,40 @@ from bs4 import BeautifulSoup
class ChromeExtension:
"""scrape chome extension for user number"""
HEADERS = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36" # noqa: E501
}
def __init__(self, extension_id):
self.extension_id = extension_id
def get(self):
"""get parsed users"""
soup = self.get_soup()
if not soup:
return 0
users = self.parse_field(soup)
return users
def get_soup(self):
"""get the soup"""
url = (
"https://chrome.google.com/webstore/detail/"
+ f"{self.extension_id}?hl=en&authuser=0"
)
response = requests.get(url).text
soup = BeautifulSoup(response, "html.parser")
url = f"https://chromewebstore.google.com/detail/tubearchivist-companion/{self.extension_id}?hl=en&authuser=0" # noqa: E501
response = requests.get(url, headers=self.HEADERS, timeout=30)
if not response.ok:
print(
f"failed to get {url}, {response.status_code} {response.text}"
)
return None
soup = BeautifulSoup(response.text, "html.parser")
return soup
def parse_field(self, soup):
"""extract the number"""
char_field = soup.find("span", {"class": "e-f-ih"}).text
char_field = soup.find("div", {"class": "F9iKBc"}).text
users = int(re.sub(r"[^\d]+", "", char_field))
return users

View File

@ -1,115 +0,0 @@
#!/usr/bin/env python
""" check requirements.txt for outdated packages """
import pathlib
import requests
class Requirements:
"""handle requirements.txt"""
FILE_PATH = "tilefy/requirements.txt"
LOCK = "/tmp/tilefy-requirements.lock"
def __init__(self):
self.exists = self.checked_today()
self.all_requirements = False
self.all_updates = False
def checked_today(self):
"""skip requirements check when lock file exists"""
exists = pathlib.Path(self.LOCK).exists()
return exists
def look_for_updates(self):
"""look through requirements and check for updates"""
self.all_requirements = self.get_dependencies()
self.all_updates = self.check_packages()
def get_dependencies(self):
"""read out requirements.txt"""
all_requirements = []
with open(self.FILE_PATH, "r", encoding="utf-8") as f:
dependencies = f.readlines()
for dependency in dependencies:
package, version = dependency.split("==")
all_requirements.append((package, version.strip()))
all_requirements.sort(key=lambda x: x[0].lower())
return all_requirements
def check_packages(self):
"""compare installed with remote version"""
total = len(self.all_requirements)
print(f"checking versions for {total} packages...")
all_updates = {}
for dependency in self.all_requirements:
package, version_installed = dependency
url = f"https://pypi.org/pypi/{package}/json"
response = requests.get(url).json()
version_remote = response["info"]["version"]
homepage = response["info"]["home_page"]
if version_remote != version_installed:
to_update = {
package: {"from": version_installed, "to": version_remote}
}
all_updates.update(to_update)
message = (
f"update {package} {version_installed}"
+ f"==> {version_remote}\n {homepage}"
)
print(message)
if not all_updates:
print("no updates found")
# remember that
pathlib.Path(self.LOCK).touch()
return all_updates
def apply_updates(self):
"""update requirements.txt file with new versions"""
to_write = []
for requirement in self.all_requirements:
package, old_version = requirement
if package in self.all_updates.keys():
package_version = self.all_updates[package]["to"]
else:
package_version = old_version
to_write.append(f"{package}=={package_version}\n")
with open(self.FILE_PATH, "w", encoding="utf-8") as f:
f.writelines(to_write)
print("requirements.txt updates")
def main():
"""main to check for updates"""
handler = Requirements()
if handler.exists:
return
handler.look_for_updates()
if handler.all_updates:
input_response = input("\nupdate requirements.txt? [y/n] ")
if input_response == "y":
handler.apply_updates()
else:
print("skip update...")
if __name__ == "__main__":
main()