-
Notifications
You must be signed in to change notification settings - Fork 3
/
purge_image_scales.py
98 lines (89 loc) · 2.86 KB
/
purge_image_scales.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Run this with:
# bin/instance run scripts/purge_image_scales.py
#
# Add --dry-run to change nothing and only get a report.
#
# For updates and more such scripts, see https://github.com/zestsoftware/plonescripts
import sys
import transaction
from Products.CMFCore.utils import getToolByName
from plone.scale.storage import AnnotationStorage
from zope.component.hooks import setSite
# Keep scales of at most X days older than their context:
DAYS = -1
# Commit after these many changes:
LIMIT = 1000
if "--dry-run" in sys.argv:
dry_run = True
print("Dry run selected, will not commit changes.")
else:
dry_run = False
# Get all Plone Sites. 'app' is the Zope root.
plones = [
obj for obj in app.objectValues() if getattr(obj, "portal_type", "") == "Plone Site"
]
def commit(note):
print(note)
if dry_run:
print("Dry run selected, not committing.")
return
# Commit transaction and add note.
tr = transaction.get()
tr.note(note)
transaction.commit()
for site in plones:
print("")
print("Handling Plone Site %s." % site.id)
setSite(site)
catalog = getToolByName(site, "portal_catalog")
count = 0
purged = 0
if hasattr(catalog, "getAllBrains"):
brains = catalog.getAllBrains()
else:
brains = catalog.unrestrictedSearchResults()
for brain in brains:
try:
obj = brain.getObject()
except:
continue
savepoint = transaction.savepoint()
ann = AnnotationStorage(obj)
try:
ann.storage
except TypeError:
# This happens when the context cannot be annotated, for
# example for a plone.app.discussion comment.
continue
# We want to remove all scales that are X days older than the
# last modification date of the object.
final_date = obj.modified() - DAYS
changed = False
to_delete = []
for key, value in ann.items():
if value["modified"] < final_date.millis():
to_delete.append(key)
changed = True
for key in to_delete:
# This may easily give an error, as it tries to remove
# two keys: del ann[key]
del ann.storage[key]
purged += len(to_delete)
if not changed:
# This avoids adding an empty annotation for items that
# will never store scales.
savepoint.rollback()
else:
count += 1
if count % LIMIT == 0:
note = (
"Purged %d outdated image scales for %d items in "
"Plone Site %s." % (purged, count, site.id)
)
commit(note)
note = (
"Finished purging %d outdated image scales for %d items in "
"Plone Site %s." % (purged, count, site.id)
)
commit(note)
print("Done.")