mirror of https://github.com/bbilly1/tilefy.git
Compare commits
7 Commits
5b61ad3349
...
6c1d57a654
Author | SHA1 | Date |
---|---|---|
Simon | 6c1d57a654 | |
Simon | 14263c8aa4 | |
Simon | d8f54da49b | |
Simon | 046603b897 | |
Simon | 2d6ad2c504 | |
Simon | 13983f4258 | |
Simon | f1f5a0b582 |
|
@ -1,4 +1,6 @@
|
||||||
.vscode
|
.vscode
|
||||||
|
.venv
|
||||||
|
.mypy_cache
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
# testing logos
|
# testing logos
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# build requirements
|
# 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 && \
|
RUN apt-get -y update && \
|
||||||
apt-get -y install --no-install-recommends \
|
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
|
# 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
|
ARG INSTALL_DEBUG
|
||||||
ENV PYTHONUNBUFFERED 1
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
|
18
deploy.sh
18
deploy.sh
|
@ -9,6 +9,8 @@ function rebuild_test {
|
||||||
rsync -a --progress --delete-after \
|
rsync -a --progress --delete-after \
|
||||||
--exclude ".git" \
|
--exclude ".git" \
|
||||||
--exclude ".gitignore" \
|
--exclude ".gitignore" \
|
||||||
|
--exclude ".mypy_cache" \
|
||||||
|
--exclude ".venv" \
|
||||||
--exclude "**/cache" \
|
--exclude "**/cache" \
|
||||||
--exclude "**/__pycache__/" \
|
--exclude "**/__pycache__/" \
|
||||||
--exclude "db.sqlite3" \
|
--exclude "db.sqlite3" \
|
||||||
|
@ -36,12 +38,12 @@ function validate {
|
||||||
echo "running black"
|
echo "running black"
|
||||||
black --diff --color --check -l 79 "$check_path"
|
black --diff --color --check -l 79 "$check_path"
|
||||||
echo "running codespell"
|
echo "running codespell"
|
||||||
codespell --skip="./.git" "$check_path"
|
codespell --skip="./.git,./.venv,./.mypy_cache" "$check_path"
|
||||||
echo "running flake8"
|
echo "running flake8"
|
||||||
flake8 "$check_path" --count --max-complexity=10 --max-line-length=79 \
|
flake8 "$check_path" --count --max-complexity=10 --max-line-length=79 \
|
||||||
--show-source --statistics
|
--show-source --statistics --exclude ".venv"
|
||||||
echo "running isort"
|
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"
|
printf " \n> all validations passed\n"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,10 +69,8 @@ function docker_publish {
|
||||||
echo "build and push $VERSION?"
|
echo "build and push $VERSION?"
|
||||||
read -rn 1
|
read -rn 1
|
||||||
|
|
||||||
# multiarch fix
|
|
||||||
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
|
||||||
# start build
|
# start build
|
||||||
sudo docker buildx build \
|
docker buildx build \
|
||||||
--platform linux/amd64,linux/arm64 \
|
--platform linux/amd64,linux/arm64 \
|
||||||
-t bbilly1/tilefy \
|
-t bbilly1/tilefy \
|
||||||
-t bbilly1/tilefy:"$VERSION" --push .
|
-t bbilly1/tilefy:"$VERSION" --push .
|
||||||
|
@ -92,8 +92,8 @@ function sync_unstable {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# start amd64 build
|
# start amd64 build
|
||||||
sudo docker buildx build \
|
docker buildx build \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64,linux/arm64 \
|
||||||
-t bbilly1/tilefy:unstable --push .
|
-t bbilly1/tilefy:unstable --push .
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,6 @@ function sync_unstable {
|
||||||
if [[ $1 == "test" ]]; then
|
if [[ $1 == "test" ]]; then
|
||||||
rebuild_test
|
rebuild_test
|
||||||
elif [[ $1 == "validate" ]]; then
|
elif [[ $1 == "validate" ]]; then
|
||||||
# check package versions in requirements.txt for updates
|
|
||||||
python version_check.py
|
|
||||||
validate "$2"
|
validate "$2"
|
||||||
elif [[ $1 == "docker" ]]; then
|
elif [[ $1 == "docker" ]]; then
|
||||||
docker_publish
|
docker_publish
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
APScheduler==3.9.1.post1
|
APScheduler==3.10.4
|
||||||
beautifulsoup4==4.11.1
|
beautifulsoup4==4.12.3
|
||||||
flask==2.2.2
|
flask==3.0.2
|
||||||
Pillow==9.3.0
|
Pillow==10.2.0
|
||||||
PyYAML==6.0
|
PyYAML==6.0.1
|
||||||
redis==4.3.5
|
redis==5.0.1
|
||||||
requests==2.28.1
|
requests==2.31.0
|
||||||
uwsgi==2.0.21
|
uwsgi==2.0.24
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Api:
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def plugin(self):
|
def plugin(self):
|
||||||
"""make request with pugin"""
|
"""make request with plugin"""
|
||||||
plugin_name = self.tile_config["plugin"]["name"]
|
plugin_name = self.tile_config["plugin"]["name"]
|
||||||
item_id = self.tile_config["plugin"]["id"]
|
item_id = self.tile_config["plugin"]["id"]
|
||||||
if plugin_name == "chrome-extension-users":
|
if plugin_name == "chrome-extension-users":
|
||||||
|
|
|
@ -9,30 +9,40 @@ from bs4 import BeautifulSoup
|
||||||
class ChromeExtension:
|
class ChromeExtension:
|
||||||
"""scrape chome extension for user number"""
|
"""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):
|
def __init__(self, extension_id):
|
||||||
self.extension_id = extension_id
|
self.extension_id = extension_id
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
"""get parsed users"""
|
"""get parsed users"""
|
||||||
soup = self.get_soup()
|
soup = self.get_soup()
|
||||||
|
if not soup:
|
||||||
|
return 0
|
||||||
|
|
||||||
users = self.parse_field(soup)
|
users = self.parse_field(soup)
|
||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
def get_soup(self):
|
def get_soup(self):
|
||||||
"""get the soup"""
|
"""get the soup"""
|
||||||
url = (
|
url = f"https://chromewebstore.google.com/detail/tubearchivist-companion/{self.extension_id}?hl=en&authuser=0" # noqa: E501
|
||||||
"https://chrome.google.com/webstore/detail/"
|
response = requests.get(url, headers=self.HEADERS, timeout=30)
|
||||||
+ f"{self.extension_id}?hl=en&authuser=0"
|
if not response.ok:
|
||||||
)
|
print(
|
||||||
response = requests.get(url).text
|
f"failed to get {url}, {response.status_code} {response.text}"
|
||||||
soup = BeautifulSoup(response, "html.parser")
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
soup = BeautifulSoup(response.text, "html.parser")
|
||||||
|
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
def parse_field(self, soup):
|
def parse_field(self, soup):
|
||||||
"""extract the number"""
|
"""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))
|
users = int(re.sub(r"[^\d]+", "", char_field))
|
||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
115
version_check.py
115
version_check.py
|
@ -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()
|
|
Loading…
Reference in New Issue