blob: 8decc48a59d99c8624d90ad27b9cd0b116bb7aed (
plain)
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
|
import sys
from django.core.management.base import NoArgsCommand
from django.db import transaction
from askbot.models import signals
from askbot.utils import console
FORMAT_STRING = '%6.2f%%'#to print progress in percent
class NoArgsJob(NoArgsCommand):
"""Base class for a job command -
the one that runs the same operation on
sets of items - each item operation in its own
transaction and prints progress in % of items
completed
The subclass must implement __init__() method
where self.batches data structure must be defined as follows
(#the whole thing is a tuple
{#batch is described by a dictionary
'title': <string>,
'query_set': <query set for the items>,
'function': <function or callable that performs
an operation on a single item
and returns True if item was changed
False otherwise
item is given as argument
>,
'items_changed_message': <string with one %d placeholder>,
'nothing_changed_message': <string>
},
#more batch descriptions
)
"""
batches = ()
def handle_noargs(self, **options):
"""handler function that removes all signal listeners
then runs the job and finally restores the listerers
"""
signal_data = signals.pop_all_db_signal_receivers()
self.run_command(**options)
signals.set_all_db_signal_receivers(signal_data)
def run_command(self, **options):
"""runs the batches"""
for batch in self.batches:
self.run_batch(batch)
@transaction.commit_manually
def run_batch(self, batch):
"""runs the single batch
prints batch title
then loops through the query set
and prints progress in %
afterwards there will be a short summary
"""
sys.stdout.write(batch['title'].encode('utf-8'))
changed_count = 0
checked_count = 0
total_count = batch['query_set'].count()
if total_count == 0:
transaction.commit()
return
for item in batch['query_set'].all():
item_changed = batch['function'](item)
transaction.commit()
if item_changed:
changed_count += 1
checked_count += 1
progress = 100*float(checked_count)/float(total_count)
console.print_progress(FORMAT_STRING, progress)
print FORMAT_STRING % 100
if changed_count:
print batch['changed_count_message'] % changed_count
else:
print batch['nothing_changed_message']
|