forked from public/mirror-checker
parent
4a8a7918b4
commit
63a0fae661
@ -0,0 +1,138 @@ |
||||
# Byte-compiled / optimized / DLL files |
||||
__pycache__/ |
||||
*.py[cod] |
||||
*$py.class |
||||
|
||||
# C extensions |
||||
*.so |
||||
|
||||
# Distribution / packaging |
||||
.Python |
||||
build/ |
||||
develop-eggs/ |
||||
dist/ |
||||
downloads/ |
||||
eggs/ |
||||
.eggs/ |
||||
lib/ |
||||
lib64/ |
||||
parts/ |
||||
sdist/ |
||||
var/ |
||||
wheels/ |
||||
share/python-wheels/ |
||||
*.egg-info/ |
||||
.installed.cfg |
||||
*.egg |
||||
MANIFEST |
||||
|
||||
# PyInstaller |
||||
# Usually these files are written by a python script from a template |
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||
*.manifest |
||||
*.spec |
||||
|
||||
# Installer logs |
||||
pip-log.txt |
||||
pip-delete-this-directory.txt |
||||
|
||||
# Unit test / coverage reports |
||||
htmlcov/ |
||||
.tox/ |
||||
.nox/ |
||||
.coverage |
||||
.coverage.* |
||||
.cache |
||||
nosetests.xml |
||||
coverage.xml |
||||
*.cover |
||||
*.py,cover |
||||
.hypothesis/ |
||||
.pytest_cache/ |
||||
cover/ |
||||
|
||||
# Translations |
||||
*.mo |
||||
*.pot |
||||
|
||||
# Django stuff: |
||||
*.log |
||||
local_settings.py |
||||
db.sqlite3 |
||||
db.sqlite3-journal |
||||
|
||||
# Flask stuff: |
||||
instance/ |
||||
.webassets-cache |
||||
|
||||
# Scrapy stuff: |
||||
.scrapy |
||||
|
||||
# Sphinx documentation |
||||
docs/_build/ |
||||
|
||||
# PyBuilder |
||||
.pybuilder/ |
||||
target/ |
||||
|
||||
# Jupyter Notebook |
||||
.ipynb_checkpoints |
||||
|
||||
# IPython |
||||
profile_default/ |
||||
ipython_config.py |
||||
|
||||
# pyenv |
||||
# For a library or package, you might want to ignore these files since the code is |
||||
# intended to run in multiple environments; otherwise, check them in: |
||||
# .python-version |
||||
|
||||
# pipenv |
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||
# install all needed dependencies. |
||||
#Pipfile.lock |
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow |
||||
__pypackages__/ |
||||
|
||||
# Celery stuff |
||||
celerybeat-schedule |
||||
celerybeat.pid |
||||
|
||||
# SageMath parsed files |
||||
*.sage.py |
||||
|
||||
# Environments |
||||
.env |
||||
.venv |
||||
env/ |
||||
venv/ |
||||
ENV/ |
||||
env.bak/ |
||||
venv.bak/ |
||||
|
||||
# Spyder project settings |
||||
.spyderproject |
||||
.spyproject |
||||
|
||||
# Rope project settings |
||||
.ropeproject |
||||
|
||||
# mkdocs documentation |
||||
/site |
||||
|
||||
# mypy |
||||
.mypy_cache/ |
||||
.dmypy.json |
||||
dmypy.json |
||||
|
||||
# Pyre type checker |
||||
.pyre/ |
||||
|
||||
# pytype static type analyzer |
||||
.pytype/ |
||||
|
||||
# Cython debug symbols |
||||
cython_debug/ |
@ -0,0 +1,28 @@ |
||||
""" |
||||
Contains Arch class |
||||
""" |
||||
|
||||
from datetime import datetime, timedelta |
||||
import requests |
||||
from distro import Distro |
||||
from constants import CSC_MIRROR |
||||
|
||||
class Arch(Distro): |
||||
"""Arch class""" |
||||
@staticmethod |
||||
def name(): |
||||
"""Get name of Arch""" |
||||
return "Arch" |
||||
|
||||
@staticmethod |
||||
def check(): |
||||
"""Check if Arch packages are up-to-date""" |
||||
arch_json = requests.get("https://archlinux.org/mirrors/status/json/").json() |
||||
last_check_str = arch_json["last_check"] |
||||
last_sync_str = [url for url in arch_json["urls"] if url["url"] == \ |
||||
f"{CSC_MIRROR}archlinux/"][0]["last_sync"] |
||||
last_check_dt = datetime.strptime(last_check_str, "%Y-%m-%dT%H:%M:%S.%fZ") |
||||
last_sync_dt = datetime.strptime(last_sync_str, "%Y-%m-%dT%H:%M:%SZ") |
||||
# According to https://archlinux.org/mirrors/status/: |
||||
# Due to the timing of mirror checks, any value under one hour should be viewed as ideal |
||||
return last_check_dt < last_sync_dt + timedelta(hours = 1) |
@ -0,0 +1,3 @@ |
||||
"""Contains shared constants""" |
||||
|
||||
CSC_MIRROR = "http://mirror.csclub.uwaterloo.ca/" |
@ -0,0 +1,31 @@ |
||||
""" |
||||
Contains Debian class |
||||
""" |
||||
|
||||
from datetime import datetime, timedelta |
||||
import requests |
||||
from distro import Distro |
||||
from constants import CSC_MIRROR |
||||
|
||||
class Debian(Distro): |
||||
"""Debian class""" |
||||
@staticmethod |
||||
def __get_dt(trace_file_url): |
||||
"""Get Debian datetime object from trace file""" |
||||
response_text = requests.get(trace_file_url).text |
||||
time_str = response_text.split('\n')[0] |
||||
return datetime.strptime(time_str, "%a %b %d %H:%M:%S UTC %Y") |
||||
|
||||
@staticmethod |
||||
def name(): |
||||
"""Get name of Debian""" |
||||
return "Debian" |
||||
|
||||
@staticmethod |
||||
def check(): |
||||
"""Check if Debian packages are up-to-date""" |
||||
official_dt = Debian.__get_dt("https://ftp-master.debian.org/debian/project/trace/master") |
||||
csc_dt = Debian.__get_dt(f"{CSC_MIRROR}debian/project/trace/master") |
||||
# Keep the table cell at https://mirror-master.debian.org/status/mirror-status.html |
||||
# green and not yellow |
||||
return official_dt < csc_dt + timedelta(hours = 7) |
@ -0,0 +1,25 @@ |
||||
""" |
||||
Contains abstract class for a distro |
||||
""" |
||||
|
||||
from abc import ABC, abstractmethod |
||||
|
||||
class Distro(ABC): |
||||
"""Abstract class for a distro""" |
||||
@staticmethod |
||||
@abstractmethod |
||||
def name(): |
||||
"""Get name of distro""" |
||||
raise NotImplementedError |
||||
|
||||
@staticmethod |
||||
@abstractmethod |
||||
def check(): |
||||
"""Check if distro packages are up-to-date""" |
||||
raise NotImplementedError |
||||
|
||||
@classmethod |
||||
def print_output(cls, is_successful): |
||||
"""Print final output of distro""" |
||||
output = "Success: {} up-to-date" if is_successful else "Failure: {} out-of-sync" |
||||
print(output.format(cls.name())) |
@ -0,0 +1,30 @@ |
||||
""" |
||||
Contains Kernel class |
||||
""" |
||||
|
||||
import requests |
||||
from distro import Distro |
||||
from constants import CSC_MIRROR |
||||
|
||||
class Kernel(Distro): |
||||
"""Kernel class""" |
||||
@staticmethod |
||||
def __get_line_count(checksum_file_url): |
||||
"""Get Kernel line count of checksum file""" |
||||
response_text = requests.get(checksum_file_url).text |
||||
return len(response_text.split('\n')) |
||||
|
||||
@staticmethod |
||||
def name(): |
||||
"""Get name of Kernel""" |
||||
return "Kernel" |
||||
|
||||
@staticmethod |
||||
def check(): |
||||
"""Check if Kernel packages are up-to-date""" |
||||
official_line_count = Kernel.__get_line_count( |
||||
"https://mirrors.edge.kernel.org/pub/linux/kernel/next/sha256sums.asc") |
||||
csc_line_count = Kernel.__get_line_count( |
||||
f"{CSC_MIRROR}kernel.org/linux/kernel/next/sha256sums.asc") |
||||
# A new update on a certain day adds 2 new lines |
||||
return official_line_count <= csc_line_count + 2 |
@ -0,0 +1,28 @@ |
||||
""" |
||||
Contains OpenBSD class |
||||
""" |
||||
|
||||
import requests |
||||
from distro import Distro |
||||
from constants import CSC_MIRROR |
||||
|
||||
class OpenBSD(Distro): |
||||
"""OpenBSD class""" |
||||
@staticmethod |
||||
def __get_sec(timestamp_file_url): |
||||
"""Get OpenBSD seconds since the Epoch from timestamp file""" |
||||
sec_str = requests.get(timestamp_file_url).text |
||||
return int(sec_str) |
||||
|
||||
@staticmethod |
||||
def name(): |
||||
"""Get name of OpenBSD""" |
||||
return "OpenBSD" |
||||
|
||||
@staticmethod |
||||
def check(): |
||||
"""Check if OpenBSD packages are up-to-date""" |
||||
official_sec = OpenBSD.__get_sec("https://ftp.openbsd.org/pub/OpenBSD/timestamp") |
||||
csc_sec = OpenBSD.__get_sec(f"{CSC_MIRROR}OpenBSD/timestamp") |
||||
# Out-of-sync by 1 day maximum |
||||
return official_sec < csc_sec + 86400 |
Loading…
Reference in new issue