import hashlib import urllib3 import os class Hashi: url_headers = {"user-agent": "hashi (a file hash checker)/0.1"} hash_algorithm = hashlib.sha256() encoded = "utf-8" def __init__(self): """Initialise libraries.""" self.http = urllib3.PoolManager(headers=self.url_headers) urllib3.disable_warnings() self.hash_update = self.hash_algorithm.update self.hash_hex = self.hash_algorithm.hexdigest def fetch_url(self, url, path): """Fetch a remote text url and save the contents as an UTF-8 file.""" resp = self.http.request("GET", url) os.makedirs(path.rsplit("/", 1)[0], exist_ok=True) with open(path, "w", encoding=self.encoded) as fh: fh.write(resp.data.decode(self.encoded)) def get_hash(self, file_path): """Given a text file path, get the hash of the file contents.""" with open(file_path, "r") as fh: bf = fh.read() self.hash_update(bf.encode(self.encoded)) return self.hash_hex() def check_hash(self, file_path, hash_path): """Compare a file hash with another previously saved hash. Return a dictionary with a boolean indicating whether the file hash has changed, the old and new hashes.""" has_change = {"changed": False, "old": "", "new": ""} cached_hash = "" new_hash = self.get_hash(file_path) try: with open(hash_path, "r") as fh: cached_hash = fh.read() except FileNotFoundError: # Treat as changed (a call to update) has_change = {"changed": True, "old": "", "new": new_hash} if new_hash != cached_hash: has_change = {"changed": True, "old": cached_hash, "new": new_hash} return has_change