chellow 1760028799.0.0__py3-none-any.whl → 1761056531.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of chellow might be problematic. Click here for more details.
- chellow/dloads.py +2 -2
- chellow/e/views.py +1 -1
- chellow/reports/report_247.py +1 -4
- chellow/reports/report_channel_snags.py +288 -0
- chellow/templates/e/channel_snags.html +32 -100
- chellow/templates/macros.html +14 -4
- chellow/templates/reports/channel_snags.html +91 -0
- chellow/utils.py +14 -3
- {chellow-1760028799.0.0.dist-info → chellow-1761056531.0.0.dist-info}/METADATA +1 -1
- {chellow-1760028799.0.0.dist-info → chellow-1761056531.0.0.dist-info}/RECORD +11 -10
- chellow/reports/report_233.py +0 -150
- {chellow-1760028799.0.0.dist-info → chellow-1761056531.0.0.dist-info}/WHEEL +0 -0
chellow/dloads.py
CHANGED
|
@@ -91,7 +91,7 @@ class DloadFile:
|
|
|
91
91
|
def open_file(base, user, mode="r", newline=None, is_zip=False):
|
|
92
92
|
global download_id
|
|
93
93
|
|
|
94
|
-
base =
|
|
94
|
+
base = "".join(x if (x.isalnum() or x in "_.") else "_" for x in base)
|
|
95
95
|
try:
|
|
96
96
|
lock.acquire()
|
|
97
97
|
if len(list(download_path.iterdir())) == 0:
|
|
@@ -108,7 +108,7 @@ def open_file(base, user, mode="r", newline=None, is_zip=False):
|
|
|
108
108
|
un = user.proxy_username
|
|
109
109
|
else:
|
|
110
110
|
un = user.email_address
|
|
111
|
-
uname =
|
|
111
|
+
uname = "".join(x if (x.isalnum() or x in "_") else "_" for x in un)
|
|
112
112
|
|
|
113
113
|
names = tuple("_".join((serial, v, uname, base)) for v in ("RUNNING", "FINISHED"))
|
|
114
114
|
running_name, finished_name = tuple(download_path / name for name in names)
|
chellow/e/views.py
CHANGED
|
@@ -381,7 +381,7 @@ def channel_snags_get():
|
|
|
381
381
|
total_snags_q = total_snags_q.where(Era.dc_contract == contract)
|
|
382
382
|
snags_q = snags_q.where(Era.dc_contract == contract)
|
|
383
383
|
|
|
384
|
-
total_snags = g.sess.
|
|
384
|
+
total_snags = g.sess.scalars(total_snags_q).one()
|
|
385
385
|
|
|
386
386
|
snag_groups = []
|
|
387
387
|
prev_snag = None
|
chellow/reports/report_247.py
CHANGED
|
@@ -1116,10 +1116,7 @@ def do_post(sess):
|
|
|
1116
1116
|
exp_mpan_core if imp_mpan_core is None else imp_mpan_core
|
|
1117
1117
|
]
|
|
1118
1118
|
|
|
1119
|
-
|
|
1120
|
-
compression = req_bool("compression")
|
|
1121
|
-
else:
|
|
1122
|
-
compression = True
|
|
1119
|
+
compression = req_bool("compression")
|
|
1123
1120
|
|
|
1124
1121
|
user = g.user
|
|
1125
1122
|
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import sys
|
|
3
|
+
import threading
|
|
4
|
+
import traceback
|
|
5
|
+
|
|
6
|
+
from dateutil.relativedelta import relativedelta
|
|
7
|
+
|
|
8
|
+
from flask import g, redirect, render_template
|
|
9
|
+
|
|
10
|
+
from sqlalchemy.orm import joinedload
|
|
11
|
+
from sqlalchemy.sql.expression import false, select, true
|
|
12
|
+
|
|
13
|
+
from werkzeug.exceptions import BadRequest
|
|
14
|
+
|
|
15
|
+
from chellow.dloads import open_file
|
|
16
|
+
from chellow.models import (
|
|
17
|
+
Channel,
|
|
18
|
+
Contract,
|
|
19
|
+
Era,
|
|
20
|
+
Party,
|
|
21
|
+
RSession,
|
|
22
|
+
Site,
|
|
23
|
+
SiteEra,
|
|
24
|
+
Snag,
|
|
25
|
+
Supply,
|
|
26
|
+
User,
|
|
27
|
+
)
|
|
28
|
+
from chellow.utils import (
|
|
29
|
+
csv_make_val,
|
|
30
|
+
hh_before,
|
|
31
|
+
req_bool,
|
|
32
|
+
req_int,
|
|
33
|
+
req_int_none,
|
|
34
|
+
req_str,
|
|
35
|
+
utc_datetime_now,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _make_rows(
|
|
40
|
+
sess,
|
|
41
|
+
now,
|
|
42
|
+
contract,
|
|
43
|
+
days_hidden,
|
|
44
|
+
is_ignored,
|
|
45
|
+
show_settlement,
|
|
46
|
+
only_ongoing,
|
|
47
|
+
days_long_hidden,
|
|
48
|
+
limit=None,
|
|
49
|
+
):
|
|
50
|
+
cutoff_date = now - relativedelta(days=days_hidden)
|
|
51
|
+
q = (
|
|
52
|
+
select(Snag, Channel, Era, Supply, SiteEra, Site, Contract)
|
|
53
|
+
.join(Channel, Snag.channel_id == Channel.id)
|
|
54
|
+
.join(Era, Channel.era_id == Era.id)
|
|
55
|
+
.join(Supply, Era.supply_id == Supply.id)
|
|
56
|
+
.join(SiteEra, Era.site_eras)
|
|
57
|
+
.join(Site, SiteEra.site_id == Site.id)
|
|
58
|
+
.join(Contract, Era.dc_contract_id == Contract.id)
|
|
59
|
+
.where(
|
|
60
|
+
SiteEra.is_physical == true(),
|
|
61
|
+
Snag.start_date < cutoff_date,
|
|
62
|
+
)
|
|
63
|
+
.order_by(
|
|
64
|
+
Site.code,
|
|
65
|
+
Supply.id,
|
|
66
|
+
Channel.imp_related,
|
|
67
|
+
Channel.channel_type,
|
|
68
|
+
Snag.description,
|
|
69
|
+
Snag.start_date,
|
|
70
|
+
Snag.id,
|
|
71
|
+
)
|
|
72
|
+
.options(joinedload(Era.dc_contract))
|
|
73
|
+
)
|
|
74
|
+
if contract is not None:
|
|
75
|
+
q = q.where(Era.dc_contract == contract)
|
|
76
|
+
|
|
77
|
+
if not is_ignored:
|
|
78
|
+
q = q.where(Snag.is_ignored == false())
|
|
79
|
+
|
|
80
|
+
if show_settlement == "yes":
|
|
81
|
+
q = q.join(Party, Supply.dno_id == Party.id).where(Party.dno_code != "99")
|
|
82
|
+
elif show_settlement == "no":
|
|
83
|
+
q = q.join(Party, Supply.dno_id == Party.id).where(Party.dno_code == "99")
|
|
84
|
+
elif show_settlement == "both":
|
|
85
|
+
pass
|
|
86
|
+
else:
|
|
87
|
+
raise BadRequest("show_settlement must be 'yes', 'no' or 'both'.")
|
|
88
|
+
|
|
89
|
+
snag_groups = []
|
|
90
|
+
prev_snag = None
|
|
91
|
+
for snag, channel, era, supply, site_era, site, contract in sess.execute(q):
|
|
92
|
+
snag_start = snag.start_date
|
|
93
|
+
snag_finish = snag.finish_date
|
|
94
|
+
|
|
95
|
+
if snag_finish is None:
|
|
96
|
+
duration = now - snag_start
|
|
97
|
+
age_of_snag = None
|
|
98
|
+
else:
|
|
99
|
+
duration = snag_finish - snag_start
|
|
100
|
+
if hh_before(cutoff_date, snag_finish):
|
|
101
|
+
age_of_snag = None
|
|
102
|
+
else:
|
|
103
|
+
delta = now - snag_finish
|
|
104
|
+
age_of_snag = delta.days
|
|
105
|
+
|
|
106
|
+
if only_ongoing and age_of_snag is not None:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
if days_long_hidden is not None and duration < days_long_hidden:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
if (
|
|
113
|
+
prev_snag is None
|
|
114
|
+
or channel.era != prev_snag.channel.era
|
|
115
|
+
or snag.start_date != prev_snag.start_date
|
|
116
|
+
or snag.finish_date != prev_snag.finish_date
|
|
117
|
+
or snag.description != prev_snag.description
|
|
118
|
+
):
|
|
119
|
+
if limit is not None and len(snag_groups) > limit:
|
|
120
|
+
break
|
|
121
|
+
|
|
122
|
+
snag_group = {
|
|
123
|
+
"snags": [],
|
|
124
|
+
"site": site,
|
|
125
|
+
"era": era,
|
|
126
|
+
"supply": supply,
|
|
127
|
+
"description": snag.description,
|
|
128
|
+
"start_date": snag.start_date,
|
|
129
|
+
"finish_date": snag.finish_date,
|
|
130
|
+
"contract": contract,
|
|
131
|
+
"contract_name": contract.name,
|
|
132
|
+
"hidden_days": days_hidden,
|
|
133
|
+
"chellow_id": snag.id,
|
|
134
|
+
"imp_mpan_core": era.imp_mpan_core,
|
|
135
|
+
"exp_mpan_core": era.exp_mpan_core,
|
|
136
|
+
"site_code": site.code,
|
|
137
|
+
"site_name": site.name,
|
|
138
|
+
"snag_description": snag.description,
|
|
139
|
+
"channel_type": channel.channel_type,
|
|
140
|
+
"is_ignored": snag.is_ignored,
|
|
141
|
+
"days_since_finished": age_of_snag,
|
|
142
|
+
"duration": duration.days,
|
|
143
|
+
}
|
|
144
|
+
snag_groups.append(snag_group)
|
|
145
|
+
snag_group["snags"].append(snag)
|
|
146
|
+
prev_snag = snag
|
|
147
|
+
|
|
148
|
+
def make_key(item):
|
|
149
|
+
return item["duration"]
|
|
150
|
+
|
|
151
|
+
snag_groups.sort(key=make_key, reverse=True)
|
|
152
|
+
return snag_groups
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def content(
|
|
156
|
+
contract_id,
|
|
157
|
+
days_hidden,
|
|
158
|
+
is_ignored,
|
|
159
|
+
user_id,
|
|
160
|
+
only_ongoing,
|
|
161
|
+
show_settlement,
|
|
162
|
+
days_long_hidden,
|
|
163
|
+
):
|
|
164
|
+
f = writer = None
|
|
165
|
+
try:
|
|
166
|
+
with RSession() as sess:
|
|
167
|
+
user = User.get_by_id(sess, user_id)
|
|
168
|
+
if contract_id is None:
|
|
169
|
+
contract = None
|
|
170
|
+
namef = "all"
|
|
171
|
+
else:
|
|
172
|
+
contract = Contract.get_dc_by_id(sess, contract_id)
|
|
173
|
+
namef = contract.name
|
|
174
|
+
|
|
175
|
+
f = open_file(f"channel_snags_{namef}.csv", user, mode="w", newline="")
|
|
176
|
+
writer = csv.writer(f, lineterminator="\n")
|
|
177
|
+
titles = (
|
|
178
|
+
"contract",
|
|
179
|
+
"hidden_days",
|
|
180
|
+
"chellow_ids",
|
|
181
|
+
"imp_mpan_core",
|
|
182
|
+
"exp_mpan_core",
|
|
183
|
+
"site_code",
|
|
184
|
+
"site_name",
|
|
185
|
+
"snag_description",
|
|
186
|
+
"channel_types",
|
|
187
|
+
"start_date",
|
|
188
|
+
"finish_date",
|
|
189
|
+
"is_ignored",
|
|
190
|
+
"days_since_finished",
|
|
191
|
+
"duration",
|
|
192
|
+
)
|
|
193
|
+
writer.writerow(titles)
|
|
194
|
+
|
|
195
|
+
now = utc_datetime_now()
|
|
196
|
+
for snag_group in _make_rows(
|
|
197
|
+
sess,
|
|
198
|
+
now,
|
|
199
|
+
contract,
|
|
200
|
+
days_hidden,
|
|
201
|
+
is_ignored,
|
|
202
|
+
show_settlement,
|
|
203
|
+
only_ongoing,
|
|
204
|
+
days_long_hidden,
|
|
205
|
+
):
|
|
206
|
+
|
|
207
|
+
vals = {
|
|
208
|
+
"contract": snag_group["contract"].name,
|
|
209
|
+
"hidden_days": days_hidden,
|
|
210
|
+
"chellow_ids": [snag.id for snag in snag_group["snags"]],
|
|
211
|
+
"imp_mpan_core": snag_group["imp_mpan_core"],
|
|
212
|
+
"exp_mpan_core": snag_group["exp_mpan_core"],
|
|
213
|
+
"site": snag_group["site"],
|
|
214
|
+
"site_code": snag_group["site"].code,
|
|
215
|
+
"site_name": snag_group["site"].name,
|
|
216
|
+
"snag_description": snag_group["description"],
|
|
217
|
+
"channel_types": [
|
|
218
|
+
f"{s.channel.imp_related}_{s.channel.channel_type}"
|
|
219
|
+
for s in snag_group["snags"]
|
|
220
|
+
],
|
|
221
|
+
"start_date": snag_group["start_date"],
|
|
222
|
+
"finish_date": snag_group["finish_date"],
|
|
223
|
+
"is_ignored": snag_group["is_ignored"],
|
|
224
|
+
"days_since_finished": snag_group["days_since_finished"],
|
|
225
|
+
"duration": snag_group["duration"],
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
writer.writerow(csv_make_val(vals[t]) for t in titles)
|
|
229
|
+
except BaseException:
|
|
230
|
+
msg = traceback.format_exc()
|
|
231
|
+
sys.stderr.write(msg)
|
|
232
|
+
writer.writerow([msg])
|
|
233
|
+
finally:
|
|
234
|
+
if f is not None:
|
|
235
|
+
f.close()
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
LIMIT = 200
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def do_get(sess):
|
|
242
|
+
contract_id = req_int_none("dc_contract_id")
|
|
243
|
+
days_hidden = req_int("days_hidden")
|
|
244
|
+
is_ignored = req_bool("is_ignored")
|
|
245
|
+
only_ongoing = req_bool("only_ongoing")
|
|
246
|
+
show_settlement = req_str("show_settlement")
|
|
247
|
+
as_csv = req_bool("as_csv")
|
|
248
|
+
days_long_hidden = req_int_none("days_long_hidden")
|
|
249
|
+
|
|
250
|
+
if as_csv:
|
|
251
|
+
args = (
|
|
252
|
+
contract_id,
|
|
253
|
+
days_hidden,
|
|
254
|
+
is_ignored,
|
|
255
|
+
g.user.id,
|
|
256
|
+
only_ongoing,
|
|
257
|
+
show_settlement,
|
|
258
|
+
)
|
|
259
|
+
threading.Thread(target=content, args=args).start()
|
|
260
|
+
return redirect("/downloads", 303)
|
|
261
|
+
else:
|
|
262
|
+
if contract_id is None:
|
|
263
|
+
contract = None
|
|
264
|
+
else:
|
|
265
|
+
contract = Contract.get_dc_by_id(sess, contract_id)
|
|
266
|
+
now = utc_datetime_now()
|
|
267
|
+
snag_groups = _make_rows(
|
|
268
|
+
sess,
|
|
269
|
+
now,
|
|
270
|
+
contract,
|
|
271
|
+
days_hidden,
|
|
272
|
+
is_ignored,
|
|
273
|
+
show_settlement,
|
|
274
|
+
only_ongoing,
|
|
275
|
+
days_long_hidden,
|
|
276
|
+
limit=LIMIT,
|
|
277
|
+
)
|
|
278
|
+
return render_template(
|
|
279
|
+
"reports/channel_snags.html",
|
|
280
|
+
contract=contract,
|
|
281
|
+
limit=LIMIT,
|
|
282
|
+
snag_groups=snag_groups,
|
|
283
|
+
days_hidden=days_hidden,
|
|
284
|
+
is_ignored=is_ignored,
|
|
285
|
+
only_ongoing=only_ongoing,
|
|
286
|
+
show_settlement=show_settlement,
|
|
287
|
+
days_long_hidden=days_long_hidden,
|
|
288
|
+
)
|
|
@@ -8,6 +8,15 @@
|
|
|
8
8
|
Channel Snags
|
|
9
9
|
{% endblock %}
|
|
10
10
|
|
|
11
|
+
{% block inside_head %}
|
|
12
|
+
<style>
|
|
13
|
+
#snags.htmx-swapping {
|
|
14
|
+
opacity: 0;
|
|
15
|
+
transition: opacity 1s ease-out;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
{% endblock %}
|
|
19
|
+
|
|
11
20
|
{% block nav %}
|
|
12
21
|
<a href="/e/dc_contracts">DC Contracts</a> »
|
|
13
22
|
{% if contract %}
|
|
@@ -17,113 +26,36 @@
|
|
|
17
26
|
{% endblock %}
|
|
18
27
|
|
|
19
28
|
{% block content %}
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
<form hx-get="/reports/channel_snags" hx-params="*" hx-include="this" hx-trigger="load, change"
|
|
30
|
+
hx-target="#snags" hx-swap="outerHTML swap:1s">
|
|
22
31
|
<fieldset>
|
|
23
|
-
<legend>
|
|
32
|
+
<legend>Filters</legend>
|
|
24
33
|
<input type="hidden" name="dc_contract_id" value="{{contract.id}}">
|
|
25
34
|
<label>Hide snags < days old</label>
|
|
26
|
-
|
|
35
|
+
{{input_text('days_hidden', initial='5', size=3, maxlength=3)}}
|
|
27
36
|
<label>Include ignored snags</label> {{input_checkbox('is_ignored', False)}}
|
|
28
|
-
<input type="submit" value="Download">
|
|
29
|
-
</fieldset>
|
|
30
|
-
</form>
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
finish date is 'ongoing' or if it finished less than 'Days Hidden' ago).
|
|
35
|
-
</p>
|
|
38
|
+
<label>Only show ongoing snags</label>
|
|
39
|
+
{{input_checkbox('only_ongoing', initial=True)}}
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
">
|
|
45
|
-
<label>Hide snags < days old</label>
|
|
46
|
-
{{input_text('days_hidden', '0', 3, 3)}}
|
|
47
|
-
<label>Include ignored snags</label> {{input_checkbox('is_ignored', False)}}
|
|
48
|
-
<input type="submit" value="Show">
|
|
49
|
-
</fieldset>
|
|
50
|
-
</form>
|
|
41
|
+
<fieldset>
|
|
42
|
+
|
|
43
|
+
<label>Show settlement only</label>
|
|
44
|
+
{{input_radio('show_settlement', 'yes', initial=False)}}
|
|
45
|
+
|
|
46
|
+
<label>Show non-settlement only</label>
|
|
47
|
+
{{input_radio('show_settlement', 'no', initial=False)}}
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{%- if not is_ignored %}
|
|
55
|
-
that aren't ignored
|
|
56
|
-
{%- endif -%}.
|
|
57
|
-
</p>
|
|
49
|
+
<label>Show both</label>
|
|
50
|
+
{{input_radio('show_settlement', 'both', initial=True)}}
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<th>Export MPAN Core</th>
|
|
67
|
-
<th>Sites</th>
|
|
68
|
-
<th>Snag Description</th>
|
|
69
|
-
<th>Channels</th>
|
|
70
|
-
<th>Duration</th>
|
|
71
|
-
</tr>
|
|
72
|
-
</thead>
|
|
73
|
-
<tbody>
|
|
74
|
-
{% for snag_group in snag_groups %}
|
|
75
|
-
<tr>
|
|
76
|
-
<td>
|
|
77
|
-
<ul>
|
|
78
|
-
{% for snag in snag_group.snags %}
|
|
79
|
-
<li>
|
|
80
|
-
<a href="/e/channel_snags/{{snag.id}}">view</a>
|
|
81
|
-
[<a href="/e/channel_snags/{{snag.id}}/edit">edit</a>]
|
|
82
|
-
{% if snag.is_ignored %} ignored{% endif %}
|
|
83
|
-
</li>
|
|
84
|
-
{% endfor %}
|
|
85
|
-
</ul>
|
|
86
|
-
</td>
|
|
87
|
-
<td>{{snag_group.era.dc_contract.name}}</td>
|
|
88
|
-
<td>
|
|
89
|
-
{% if snag_group.era.imp_mpan_core %}
|
|
90
|
-
{{snag_group.era.imp_mpan_core}}
|
|
91
|
-
{% endif %}
|
|
92
|
-
</td>
|
|
93
|
-
<td>
|
|
94
|
-
{% if snag_group.era.exp_mpan_core %}
|
|
95
|
-
{{snag_group.era.exp_mpan_core}}
|
|
96
|
-
{% endif %}
|
|
97
|
-
</td>
|
|
98
|
-
<td>
|
|
99
|
-
<ul>
|
|
100
|
-
{% for site in snag_group.sites %}
|
|
101
|
-
<li>{{site.code}} {{site.name}}</li>
|
|
102
|
-
{% endfor %}
|
|
103
|
-
</ul>
|
|
104
|
-
</td>
|
|
105
|
-
<td>{{snag_group.description}}</td>
|
|
106
|
-
<td>
|
|
107
|
-
<ul>
|
|
108
|
-
{% for snag in snag_group.snags %}
|
|
109
|
-
<li>
|
|
110
|
-
{% if snag.channel.imp_related %}
|
|
111
|
-
Import
|
|
112
|
-
{% else %}
|
|
113
|
-
Export
|
|
114
|
-
{% endif %}
|
|
115
|
-
{{snag.channel.channel_type}}
|
|
116
|
-
</li>
|
|
117
|
-
{% endfor %}
|
|
118
|
-
</ul>
|
|
119
|
-
</td>
|
|
120
|
-
<td>
|
|
121
|
-
{{snag_group.start_date|hh_format}} to
|
|
122
|
-
{{snag_group.finish_date|hh_format}}
|
|
123
|
-
</td>
|
|
124
|
-
</tr>
|
|
125
|
-
{% endfor %}
|
|
126
|
-
</tbody>
|
|
127
|
-
</table>
|
|
52
|
+
</fieldset>
|
|
53
|
+
|
|
54
|
+
<label>Hide snags < days long</label>
|
|
55
|
+
{{input_text('days_long_hidden', initial='', size=3, maxlength=3)}}
|
|
56
|
+
|
|
57
|
+
</fieldset>
|
|
58
|
+
</form>
|
|
128
59
|
|
|
60
|
+
<div id="snags"></div>
|
|
129
61
|
{% endblock %}
|
chellow/templates/macros.html
CHANGED
|
@@ -124,13 +124,23 @@
|
|
|
124
124
|
</div>
|
|
125
125
|
{%- endmacro -%}
|
|
126
126
|
|
|
127
|
-
{%- macro input_checkbox(name, initial) %}
|
|
128
|
-
<input type="checkbox" name="{{ name }}" value="
|
|
127
|
+
{%- macro input_checkbox(name, initial=False, value='true') %}
|
|
128
|
+
<input type="checkbox" name="{{ name }}" value="{{value}}"
|
|
129
129
|
{%- if request.values[name] -%}
|
|
130
|
-
{%- if request.values[name] ==
|
|
130
|
+
{%- if request.values[name] == value %} checked
|
|
131
131
|
{%- endif -%}
|
|
132
132
|
{%- else -%}
|
|
133
|
-
{%- if initial
|
|
133
|
+
{%- if initial %} checked{% endif -%}
|
|
134
|
+
{%- endif -%}>
|
|
135
|
+
{%- endmacro -%}
|
|
136
|
+
|
|
137
|
+
{%- macro input_radio(name, value, initial=False) %}
|
|
138
|
+
<input type="radio" name="{{ name }}" value="{{value}}"
|
|
139
|
+
{%- if request.values[name] -%}
|
|
140
|
+
{%- if request.values[name] == value %} checked
|
|
141
|
+
{%- endif -%}
|
|
142
|
+
{%- else -%}
|
|
143
|
+
{%- if initial %} checked{% endif -%}
|
|
134
144
|
{%- endif -%}>
|
|
135
145
|
{%- endmacro -%}
|
|
136
146
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{% extends "macros.html" %}
|
|
2
|
+
|
|
3
|
+
{% block html %}
|
|
4
|
+
<table class="sticky" id="snags">
|
|
5
|
+
<caption>
|
|
6
|
+
Snags (truncated after 200)
|
|
7
|
+
<a href="/reports/channel_snags?dc_contract_id={{contract.id}}&days_hidden={{days_hidden}}&is_ignored={{is_ignored}}&only_ongoing={{only_ongoing}}&show_settlement={{show_settlement}}&as_csv=true">Download as CSV</a>
|
|
8
|
+
</caption>
|
|
9
|
+
<thead>
|
|
10
|
+
<tr>
|
|
11
|
+
<th>View</th>
|
|
12
|
+
<th>Contract</th>
|
|
13
|
+
<th>Import MPAN Core</th>
|
|
14
|
+
<th>Export MPAN Core</th>
|
|
15
|
+
<th>Site</th>
|
|
16
|
+
<th>Description</th>
|
|
17
|
+
<th>Channels</th>
|
|
18
|
+
<th>Start Date</th>
|
|
19
|
+
<th>Finish Date</th>
|
|
20
|
+
<th>
|
|
21
|
+
<span title="Blank if the snag is ongoing (ie. if the finish date is 'ongoing' or if it finished less than 'Days Hidden' ago).">Days Since Finished</span>
|
|
22
|
+
</th>
|
|
23
|
+
<th>Duration</th>
|
|
24
|
+
<th>Comm</th>
|
|
25
|
+
</tr>
|
|
26
|
+
</thead>
|
|
27
|
+
<tbody>
|
|
28
|
+
{% for snag_group in snag_groups %}
|
|
29
|
+
<tr>
|
|
30
|
+
<td>
|
|
31
|
+
<ul>
|
|
32
|
+
{% for snag in snag_group.snags %}
|
|
33
|
+
<li>
|
|
34
|
+
<a href="/e/channel_snags/{{snag.id}}">view</a>
|
|
35
|
+
[<a href="/e/channel_snags/{{snag.id}}/edit">edit</a>]
|
|
36
|
+
{% if snag.is_ignored %} ignored{% endif %}
|
|
37
|
+
</li>
|
|
38
|
+
{% endfor %}
|
|
39
|
+
</ul>
|
|
40
|
+
</td>
|
|
41
|
+
<td>
|
|
42
|
+
<a href="/e/dc_contracts/{{snag_group.contract.id}}">{{snag_group.contract.name}}</a>
|
|
43
|
+
</td>
|
|
44
|
+
<td>
|
|
45
|
+
{% if snag_group.era.imp_mpan_core %}
|
|
46
|
+
<a href="/e/supplies/{{snag_group.supply.id}}">{{snag_group.era.imp_mpan_core}}</a>
|
|
47
|
+
{% endif %}
|
|
48
|
+
</td>
|
|
49
|
+
<td>
|
|
50
|
+
{% if snag_group.era.exp_mpan_core %}
|
|
51
|
+
<a href="/e/supplies/{{snag_group.supply.id}}">{{snag_group.era.exp_mpan_core}}</a>
|
|
52
|
+
{% endif %}
|
|
53
|
+
</td>
|
|
54
|
+
<td>
|
|
55
|
+
<a href="/sites/{{snag_group.site.id}}">{{snag_group.site.code}} {{snag_group.site.name}}</a>
|
|
56
|
+
</td>
|
|
57
|
+
<td>{{snag_group.description}}</td>
|
|
58
|
+
<td>
|
|
59
|
+
<ul>
|
|
60
|
+
{% for snag in snag_group.snags %}
|
|
61
|
+
<li>
|
|
62
|
+
{% if snag.channel.imp_related %}
|
|
63
|
+
Import
|
|
64
|
+
{% else %}
|
|
65
|
+
Export
|
|
66
|
+
{% endif %}
|
|
67
|
+
{{snag.channel.channel_type}}
|
|
68
|
+
</li>
|
|
69
|
+
{% endfor %}
|
|
70
|
+
</ul>
|
|
71
|
+
</td>
|
|
72
|
+
<td>
|
|
73
|
+
{{snag_group.start_date|hh_format}}
|
|
74
|
+
</td>
|
|
75
|
+
<td>
|
|
76
|
+
{{snag_group.finish_date|hh_format}}
|
|
77
|
+
</td>
|
|
78
|
+
<td>
|
|
79
|
+
{% if snag_group.days_since_finished %}
|
|
80
|
+
{{snag_group.days_since_finished}}
|
|
81
|
+
{% endif %}
|
|
82
|
+
</td>
|
|
83
|
+
<td>{{snag_group.duration}}</td>
|
|
84
|
+
<td>
|
|
85
|
+
<a href="/e/comms/{{snag_group.era.comm.id}}" title="{{snag_group.era.comm.description}}">{{snag_group.era.comm.code}}</a>
|
|
86
|
+
</td>
|
|
87
|
+
</tr>
|
|
88
|
+
{% endfor %}
|
|
89
|
+
</tbody>
|
|
90
|
+
</table>
|
|
91
|
+
{% endblock %}
|
chellow/utils.py
CHANGED
|
@@ -29,11 +29,15 @@ def req_str(name):
|
|
|
29
29
|
raise BadRequest(f"The field {name} is required.")
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
def
|
|
32
|
+
def req_strs(name):
|
|
33
33
|
try:
|
|
34
|
-
return request.values
|
|
34
|
+
return request.values.getlist(name)
|
|
35
35
|
except KeyError:
|
|
36
|
-
|
|
36
|
+
raise BadRequest(f"The field {name} is required.")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def req_bool(name):
|
|
40
|
+
return name in request.values
|
|
37
41
|
|
|
38
42
|
|
|
39
43
|
def req_int(name):
|
|
@@ -43,6 +47,13 @@ def req_int(name):
|
|
|
43
47
|
raise BadRequest(f"Problem parsing the field {name} as an integer: {e}")
|
|
44
48
|
|
|
45
49
|
|
|
50
|
+
def req_ints(name):
|
|
51
|
+
try:
|
|
52
|
+
return [int(v) for v in req_strs(name)]
|
|
53
|
+
except ValueError as e:
|
|
54
|
+
raise BadRequest(f"Problem parsing the field {name} as an integer: {e}")
|
|
55
|
+
|
|
56
|
+
|
|
46
57
|
def req_int_none(name):
|
|
47
58
|
val = req_str(name)
|
|
48
59
|
if val == "":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1761056531.0.0
|
|
4
4
|
Summary: Web Application for checking UK energy bills.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WessexWater/chellow
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -2,7 +2,7 @@ chellow/__init__.py,sha256=9aoSbGmHCIHwzI_c_TLSg5CeKwqAq0I6kKaMvTrTMqg,10936
|
|
|
2
2
|
chellow/api.py,sha256=mk17TfweR76DPFC8lX2SArTjai6y6YshASxqO1w-_-s,11036
|
|
3
3
|
chellow/bank_holidays.py,sha256=T_utYMwe_g1dz5X-aOTdIPryg49SvB7QsWM1yphlqG8,4423
|
|
4
4
|
chellow/commands.py,sha256=ESBe9ZWj1c3vdZgqMZ9gFvYAB3hRag2R1PzOwuw9yFo,1302
|
|
5
|
-
chellow/dloads.py,sha256=
|
|
5
|
+
chellow/dloads.py,sha256=sNAPMe4LeHqfisEubGXvraDsUS0F-ujI3WG0Md8DywM,5565
|
|
6
6
|
chellow/edi_lib.py,sha256=Lq70TUJuogoP5KGrphzUEUfyfgftEclg_iA3mpNAaDI,51324
|
|
7
7
|
chellow/fake_batch_updater.py,sha256=khAmvSUn9qN04w8C92kRg1UeyQvfLztE7QXv9tUz6nE,11611
|
|
8
8
|
chellow/general_import.py,sha256=ghybbden66VT4q5J0vYwiNg-6G2vg71EgCN_x3fvhW0,69200
|
|
@@ -12,7 +12,7 @@ chellow/proxy.py,sha256=cVXIktPlX3tQ1BYcwxq0nJXKE6r3DtFTtfFHPq55HaM,1351
|
|
|
12
12
|
chellow/rate_server.py,sha256=RwJo-AzBIdzxx7PAtboZEUH1nUjAeJckw0bk06-9oyM,5672
|
|
13
13
|
chellow/rrun.py,sha256=sWm_tuJ_6xH3T28TY1w63k1Q44N_S_p_pYF5YCeztqU,2226
|
|
14
14
|
chellow/testing.py,sha256=Dj2c1NX8lVlygueOrh2eyYawLW6qKEHxNhXVVUaNRO0,3637
|
|
15
|
-
chellow/utils.py,sha256=
|
|
15
|
+
chellow/utils.py,sha256=x6yReQkhFaFGnsuhs6PqrEkE1OfZSPrrC7IqstRXKKU,19701
|
|
16
16
|
chellow/views.py,sha256=9IUUbYjqEmQQzbYQB4w-ygCo25gecIxYVbxTXRF-YfY,86078
|
|
17
17
|
chellow/e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
chellow/e/aahedc.py,sha256=d2usudp7KYWpU6Pk3fal5EQ47EbvkvKeaFGylnb3NWw,606
|
|
@@ -45,7 +45,7 @@ chellow/e/system_price.py,sha256=6w5J7bzwFAZubE2zdOFRiS8IIrVP8hkoIOaG2yCt-Ic,623
|
|
|
45
45
|
chellow/e/tlms.py,sha256=pyL32hPiYd09FbpXVMnBjHsWFEQHs-Az945V7EShGiY,9116
|
|
46
46
|
chellow/e/tnuos.py,sha256=NBmc-f3oezrl4gviAKobljHfICTpBKxxxEGBGJi_lRk,4927
|
|
47
47
|
chellow/e/triad.py,sha256=uQIngSrz8irBXQ0Rp_s8nAUzu-y2Ms7aj4B38_Ff8y8,13720
|
|
48
|
-
chellow/e/views.py,sha256=
|
|
48
|
+
chellow/e/views.py,sha256=7WKLrqYtk018oXjmx9YBv72B5hpgOV0eTJYqsIoBYsE,234251
|
|
49
49
|
chellow/e/bill_parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
50
|
chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=hcbjxqLOe7qkDjS7enCpmfyGwm3d-pq3u5VQIaUmVTw,3796
|
|
51
51
|
chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=yoEGQS0qcrv3TWFfxELIIi8f1CyKcIzh0xVaPoz2w2s,4191
|
|
@@ -86,9 +86,8 @@ chellow/reports/report_183.py,sha256=fGONpKEIXTqIT_3dE5jZKBIesWPgLq-chHO6X22dIv0
|
|
|
86
86
|
chellow/reports/report_187.py,sha256=RCvxDnkfRu7ocKUPEX0qtVphGOBEl9RULy790uteXcQ,9915
|
|
87
87
|
chellow/reports/report_219.py,sha256=3Zs16ka6dWWY_lCDoA-ZFrlPb4vHk1LQoa2yrlTMntA,7117
|
|
88
88
|
chellow/reports/report_231.py,sha256=WARLztV2HzBFSi5_xvY_DTXVyuBBbBYiU0RazfjKw-Y,5270
|
|
89
|
-
chellow/reports/report_233.py,sha256=qJdPFuBgQAWD24BsljgGJ44L_RGdHOA1RqsxGjTWhFc,4975
|
|
90
89
|
chellow/reports/report_241.py,sha256=lfivElRkV_CZAhck0rxAuhqzgponj3aWwmwGMNQvUxg,5343
|
|
91
|
-
chellow/reports/report_247.py,sha256=
|
|
90
|
+
chellow/reports/report_247.py,sha256=pbWfM-fUeuakZxH1Ovlx7-XfUg6SL9t51swK3yMc1lc,43253
|
|
92
91
|
chellow/reports/report_29.py,sha256=ZXnq6Kg5on-IPquUsH4bn46mBVESY_WhwqDWZPXOJwo,2695
|
|
93
92
|
chellow/reports/report_291.py,sha256=BnWtxe0eWN2QKKWpwjs5-RI5LbReBKL119QbkrkNhV8,7478
|
|
94
93
|
chellow/reports/report_33.py,sha256=lt1EN_LNx6u-AgdaS3YRkPMZA33JgMcELolHF4oJUMw,16689
|
|
@@ -101,6 +100,7 @@ chellow/reports/report_87.py,sha256=udzbCuXcckWD-OHmfJCT6bwg_paYhm4vfDWlL8WM-jA,
|
|
|
101
100
|
chellow/reports/report_asset_comparison.py,sha256=Cl2NgvbclqhOVvKuUu3sajTVO2JupMfzK3bV0_K8eNs,6077
|
|
102
101
|
chellow/reports/report_batches.py,sha256=MoCv2dE-JgaJzaMjMA-kZrPkYR13uDoXer5UuF12OYc,4757
|
|
103
102
|
chellow/reports/report_bills.py,sha256=LP7XDxzO0Fp10c8xDE67e4tHTEc7nN74ESQBy762Nx4,3401
|
|
103
|
+
chellow/reports/report_channel_snags.py,sha256=RV5L3zRwFmuZws7w9H9VzLCFlQ6U3-ZU6jn4j5VydNc,8626
|
|
104
104
|
chellow/reports/report_csv_llfcs.py,sha256=mMB06b6Jems5kcQU4H4Le_fyKgVr8THP8BCx3pkvg5E,1903
|
|
105
105
|
chellow/reports/report_csv_site_hh_data.py,sha256=ik0OkGVo1bfTXLdcT3gPUHnxSkSdorzZheP3qgnOR5c,4331
|
|
106
106
|
chellow/reports/report_csv_site_snags.py,sha256=AuAy6vjL0g7vwPPAZhBqxOyITL9_jnyFj012MnUcxxk,2627
|
|
@@ -134,7 +134,7 @@ chellow/templates/home.html,sha256=7xiD6QLju3ugALzMlzTJosRyMUmQGWPK6jDF7oZbnAQ,5
|
|
|
134
134
|
chellow/templates/input_date.html,sha256=rpgB5n0LfN8Y5djN_ZiuSxqdskxzCoKrEqI7hyJkVQo,1248
|
|
135
135
|
chellow/templates/local_report.html,sha256=pV7_0QwyQ-D3OS9LXrly5pq3qprZnwTCoq6vCnMTkS4,1332
|
|
136
136
|
chellow/templates/local_reports.html,sha256=4wbfVkY4wUfSSfWjxqIsvCpIsa9k7H_dGAjznrG5jNM,701
|
|
137
|
-
chellow/templates/macros.html,sha256=
|
|
137
|
+
chellow/templates/macros.html,sha256=FlRTl9W2avRXErnS3vzeOxciGXJYoKptiR08iVmSpfw,5353
|
|
138
138
|
chellow/templates/national_grid.html,sha256=8W92tsjlqPSB0J--nyFIi-wzFae9CyDr6fODXLZp8ic,991
|
|
139
139
|
chellow/templates/non_core_auto_importer.html,sha256=s9SluRN1bHTHjd8GP6uFhk6LrZYG8dqBG3y94zUKe5Q,944
|
|
140
140
|
chellow/templates/non_core_contract.html,sha256=BdGtxErTvw4DwXLb6B2vimuU6ode3fFA-90kBmHCwYc,1754
|
|
@@ -181,7 +181,7 @@ chellow/templates/e/channel_add.html,sha256=szwQJBHx2kAoSFomXDHD0N_7PSd4drqOoAWh
|
|
|
181
181
|
chellow/templates/e/channel_edit.html,sha256=OUkdiS2NBQ_w4gmxRxXAcRToM5BT8DWWJrtQMFs-GUU,2198
|
|
182
182
|
chellow/templates/e/channel_snag.html,sha256=wBJ5KBfeJdAeRmaB0qu0AD9Z4nM5fn6tJ_8bNqTWtoo,1477
|
|
183
183
|
chellow/templates/e/channel_snag_edit.html,sha256=sUFI4Ml3F1B35x8_t_Pz3hWuQN9Xtxr3kt4u8hdxNwY,1911
|
|
184
|
-
chellow/templates/e/channel_snags.html,sha256=
|
|
184
|
+
chellow/templates/e/channel_snags.html,sha256=TgRhS6DcOMyoAowwrCjPtq9iuX6lpvG3uchcd3g80kk,1593
|
|
185
185
|
chellow/templates/e/comm.html,sha256=DSlAaDg1r4KYq9VUgDtt2lgW6apZjZvwhMujIJINmps,383
|
|
186
186
|
chellow/templates/e/comms.html,sha256=bUXZePnMfpKk1E71qLGOSkx8r3GxdPPD_-MosIXXq4s,434
|
|
187
187
|
chellow/templates/e/cop.html,sha256=ULv7ALFJHMUgPX96hQNm2irc3edtKYHS6fYAxvmzj8M,376
|
|
@@ -400,6 +400,7 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
|
|
|
400
400
|
chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
|
|
401
401
|
chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
|
|
402
402
|
chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
|
|
403
|
-
chellow
|
|
404
|
-
chellow-
|
|
405
|
-
chellow-
|
|
403
|
+
chellow/templates/reports/channel_snags.html,sha256=_aAgFgMlTkK2HuKFU8YisAIcUYfg6Hqhgyf5MZpdK8c,2629
|
|
404
|
+
chellow-1761056531.0.0.dist-info/METADATA,sha256=x465BtJg_0nCB84ep2IVjHyEpTTyZZixgcyJ_zKU7fk,12500
|
|
405
|
+
chellow-1761056531.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
406
|
+
chellow-1761056531.0.0.dist-info/RECORD,,
|
chellow/reports/report_233.py
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import sys
|
|
3
|
-
import threading
|
|
4
|
-
import traceback
|
|
5
|
-
|
|
6
|
-
from dateutil.relativedelta import relativedelta
|
|
7
|
-
|
|
8
|
-
from flask import g, redirect
|
|
9
|
-
|
|
10
|
-
from sqlalchemy.orm import joinedload
|
|
11
|
-
from sqlalchemy.sql.expression import false, select, true
|
|
12
|
-
|
|
13
|
-
from chellow.dloads import open_file
|
|
14
|
-
from chellow.models import (
|
|
15
|
-
Channel,
|
|
16
|
-
Contract,
|
|
17
|
-
Era,
|
|
18
|
-
Session,
|
|
19
|
-
Site,
|
|
20
|
-
SiteEra,
|
|
21
|
-
Snag,
|
|
22
|
-
Supply,
|
|
23
|
-
User,
|
|
24
|
-
)
|
|
25
|
-
from chellow.utils import (
|
|
26
|
-
csv_make_val,
|
|
27
|
-
hh_before,
|
|
28
|
-
req_bool,
|
|
29
|
-
req_int,
|
|
30
|
-
req_int_none,
|
|
31
|
-
utc_datetime_now,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def content(contract_id, days_hidden, is_ignored, user_id):
|
|
36
|
-
f = writer = None
|
|
37
|
-
try:
|
|
38
|
-
with Session() as sess:
|
|
39
|
-
user = User.get_by_id(sess, user_id)
|
|
40
|
-
if contract_id is None:
|
|
41
|
-
contract = None
|
|
42
|
-
namef = "all"
|
|
43
|
-
else:
|
|
44
|
-
contract = Contract.get_dc_by_id(sess, contract_id)
|
|
45
|
-
namef = "".join(x if x.isalnum() else "_" for x in contract.name)
|
|
46
|
-
|
|
47
|
-
f = open_file(f"channel_snags_{namef}.csv", user, mode="w", newline="")
|
|
48
|
-
writer = csv.writer(f, lineterminator="\n")
|
|
49
|
-
titles = (
|
|
50
|
-
"contract",
|
|
51
|
-
"Hidden Days",
|
|
52
|
-
"Chellow Id",
|
|
53
|
-
"Imp MPAN Core",
|
|
54
|
-
"Exp MPAN Core",
|
|
55
|
-
"Site Code",
|
|
56
|
-
"Site Name",
|
|
57
|
-
"Snag Description",
|
|
58
|
-
"Import Related?",
|
|
59
|
-
"Channel Type",
|
|
60
|
-
"Start Date",
|
|
61
|
-
"Finish Date",
|
|
62
|
-
"Is Ignored?",
|
|
63
|
-
"Days Since Snag Finished",
|
|
64
|
-
"Duration Of Snag (Days)",
|
|
65
|
-
)
|
|
66
|
-
writer.writerow(titles)
|
|
67
|
-
|
|
68
|
-
now = utc_datetime_now()
|
|
69
|
-
cutoff_date = now - relativedelta(days=days_hidden)
|
|
70
|
-
q = (
|
|
71
|
-
select(Snag, Channel, Era, Supply, SiteEra, Site)
|
|
72
|
-
.join(Channel, Snag.channel_id == Channel.id)
|
|
73
|
-
.join(Era, Channel.era_id == Era.id)
|
|
74
|
-
.join(Supply, Era.supply_id == Supply.id)
|
|
75
|
-
.join(SiteEra, Era.site_eras)
|
|
76
|
-
.join(Site, SiteEra.site_id == Site.id)
|
|
77
|
-
.where(
|
|
78
|
-
SiteEra.is_physical == true(),
|
|
79
|
-
Snag.start_date < cutoff_date,
|
|
80
|
-
)
|
|
81
|
-
.order_by(
|
|
82
|
-
Site.code,
|
|
83
|
-
Supply.id,
|
|
84
|
-
Channel.imp_related,
|
|
85
|
-
Channel.channel_type,
|
|
86
|
-
Snag.description,
|
|
87
|
-
Snag.start_date,
|
|
88
|
-
Snag.id,
|
|
89
|
-
)
|
|
90
|
-
.options(joinedload(Era.dc_contract))
|
|
91
|
-
)
|
|
92
|
-
if contract is not None:
|
|
93
|
-
q = q.where(Era.dc_contract == contract)
|
|
94
|
-
|
|
95
|
-
if not is_ignored:
|
|
96
|
-
q = q.where(Snag.is_ignored == false())
|
|
97
|
-
|
|
98
|
-
for snag, channel, era, supply, site_era, site in sess.execute(q):
|
|
99
|
-
snag_start = snag.start_date
|
|
100
|
-
snag_finish = snag.finish_date
|
|
101
|
-
imp_mc = "" if era.imp_mpan_core is None else era.imp_mpan_core
|
|
102
|
-
exp_mc = "" if era.exp_mpan_core is None else era.exp_mpan_core
|
|
103
|
-
|
|
104
|
-
if snag_finish is None:
|
|
105
|
-
duration = now - snag_start
|
|
106
|
-
age_of_snag = None
|
|
107
|
-
else:
|
|
108
|
-
duration = snag_finish - snag_start
|
|
109
|
-
if hh_before(cutoff_date, snag_finish):
|
|
110
|
-
age_of_snag = None
|
|
111
|
-
else:
|
|
112
|
-
delta = now - snag_finish
|
|
113
|
-
age_of_snag = delta.days
|
|
114
|
-
|
|
115
|
-
vals = {
|
|
116
|
-
"contract": era.dc_contract.name,
|
|
117
|
-
"Hidden Days": days_hidden,
|
|
118
|
-
"Chellow Id": snag.id,
|
|
119
|
-
"Imp MPAN Core": imp_mc,
|
|
120
|
-
"Exp MPAN Core": exp_mc,
|
|
121
|
-
"Site Code": site.code,
|
|
122
|
-
"Site Name": site.name,
|
|
123
|
-
"Snag Description": snag.description,
|
|
124
|
-
"Import Related?": channel.imp_related,
|
|
125
|
-
"Channel Type": channel.channel_type,
|
|
126
|
-
"Start Date": snag_start,
|
|
127
|
-
"Finish Date": snag_finish,
|
|
128
|
-
"Is Ignored?": snag.is_ignored,
|
|
129
|
-
"Days Since Snag Finished": age_of_snag,
|
|
130
|
-
"Duration Of Snag (Days)": duration.days,
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
writer.writerow(csv_make_val(vals[t]) for t in titles)
|
|
134
|
-
except BaseException:
|
|
135
|
-
msg = traceback.format_exc()
|
|
136
|
-
sys.stderr.write(msg)
|
|
137
|
-
writer.writerow([msg])
|
|
138
|
-
finally:
|
|
139
|
-
if f is not None:
|
|
140
|
-
f.close()
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def do_get(sess):
|
|
144
|
-
contract_id = req_int_none("dc_contract_id")
|
|
145
|
-
days_hidden = req_int("days_hidden")
|
|
146
|
-
is_ignored = req_bool("is_ignored")
|
|
147
|
-
|
|
148
|
-
args = contract_id, days_hidden, is_ignored, g.user.id
|
|
149
|
-
threading.Thread(target=content, args=args).start()
|
|
150
|
-
return redirect("/downloads", 303)
|
|
File without changes
|