Guides: procedures written and read inside ShopDB
This commit is contained in:
@@ -17,6 +17,7 @@ Storing text verbatim keeps what the author typed recoverable even if the
|
||||
rendering rules change later.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
from ..models import BLOCKTYPES
|
||||
@@ -129,3 +130,23 @@ def checklistitemcount(blocks):
|
||||
if isinstance(block, dict) and block.get('type') == 'checklist':
|
||||
total += len(block.get('items') or [])
|
||||
return total
|
||||
|
||||
|
||||
def contenthash(title, summary, tags, blocks):
|
||||
"""sha256 over everything a reader would notice changing.
|
||||
|
||||
Title, summary and tags are included, not just the blocks: renaming a guide
|
||||
or retagging it is a change worth a revision, and hashing only the body
|
||||
would silently drop it from the history.
|
||||
|
||||
Canonical by construction - the blocks are re-serialized with sorted keys
|
||||
and no whitespace, so the same content saved twice hashes the same however
|
||||
the editor happened to order its JSON that day.
|
||||
"""
|
||||
canonical = json.dumps({
|
||||
'title': (title or '').strip(),
|
||||
'summary': (summary or '').strip(),
|
||||
'tags': sorted(t.strip().lower() for t in (tags or '').split(',') if t.strip()),
|
||||
'blocks': blocks or [],
|
||||
}, sort_keys=True, separators=(',', ':'))
|
||||
return hashlib.sha256(canonical.encode('utf-8')).hexdigest()
|
||||
|
||||
Reference in New Issue
Block a user