Merge pull request #205 from priv-kweihmann/image-hash

main: add image hashing
This commit is contained in:
Ace 2022-08-25 23:47:41 +01:00 committed by GitHub
commit 4c78299531
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,7 +6,10 @@ Main class for inkycal Project
Copyright by aceisace Copyright by aceisace
""" """
import glob
import hashlib
import json import json
import os
import traceback import traceback
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
@ -168,6 +171,9 @@ class Inkycal:
# Path to store images # Path to store images
self.image_folder = image_folder self.image_folder = image_folder
# Remove old hashes
self._remove_hashes(self.image_folder)
# Give an OK message # Give an OK message
print('loaded inkycal') print('loaded inkycal')
@ -235,6 +241,45 @@ class Inkycal:
self._assemble() self._assemble()
def _image_hash(self, _in):
"""Create a md5sum of a path or a bytes stream."""
if not isinstance(_in, str):
image_bytes = _in.tobytes()
else:
try:
with open(_in) as i:
return i.read()
except FileNotFoundError:
image_bytes = None
return hashlib.md5(image_bytes).hexdigest() if image_bytes else ""
def _remove_hashes(self, basepath):
for _file in glob.glob(f"{basepath}/*.hash"):
try:
os.remove(_file)
except:
pass
def _write_image_hash(self, path, _in):
"""Write hash to a file."""
with open(path, "w") as o:
o.write(self._image_hash(_in))
def _needs_image_update(self, _list):
"""Check if any image has been updated or not.
Input a list of tuples(str, image)."""
res = False
for item in _list:
_a = self._image_hash(item[0])
_b = self._image_hash(item[1])
print("{f1}:{h1} -> {h2}".format(f1=item[0], h1=_a, h2=_b))
if _a != _b:
res = True
self._write_image_hash(item[0], item[1])
print("Refresh needed: {a}".format(a=res))
return res
def run(self): def run(self):
"""Runs main program in nonstop mode. """Runs main program in nonstop mode.
@ -264,7 +309,10 @@ class Inkycal:
errors = [] # store module numbers in here errors = [] # store module numbers in here
# short info for info-section # short info for info-section
self.info = f"{current_time.format('D MMM @ HH:mm')} " if not self.settings.get('image_hash', False):
self.info = f"{current_time.format('D MMM @ HH:mm')} "
else:
self.info = ""
for number in range(1, self._module_number): for number in range(1, self._module_number):
@ -299,6 +347,9 @@ class Inkycal:
display = self.Display display = self.Display
self._calibration_check() self._calibration_check()
if self._calibration_state:
# after calibration we have to forcefully rewrite the screen
self._remove_hashes(self.image_folder)
if self.supports_colour: if self.supports_colour:
im_black = Image.open(f"{self.image_folder}canvas.png") im_black = Image.open(f"{self.image_folder}canvas.png")
@ -310,7 +361,12 @@ class Inkycal:
im_colour = upside_down(im_colour) im_colour = upside_down(im_colour)
# render the image on the display # render the image on the display
display.render(im_black, im_colour) if not self.settings.get('image_hash', False) or self._needs_image_update([
(f"{self.image_folder}/canvas.png.hash", im_black),
(f"{self.image_folder}/canvas_colour.png.hash", im_colour)
]):
# render the image on the display
display.render(im_black, im_colour)
# Part for black-white ePapers # Part for black-white ePapers
elif not self.supports_colour: elif not self.supports_colour:
@ -321,7 +377,10 @@ class Inkycal:
if self.settings['orientation'] == 180: if self.settings['orientation'] == 180:
im_black = upside_down(im_black) im_black = upside_down(im_black)
display.render(im_black) if not self.settings.get('image_hash', False) or self._needs_image_update([
(f"{self.image_folder}/canvas.png.hash", im_black),
]):
display.render(im_black)
print(f'\nNo errors since {counter} display updates \n' print(f'\nNo errors since {counter} display updates \n'
f'program started {runtime.humanize()}') f'program started {runtime.humanize()}')