50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
|
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
|