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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# Copyright 2005-2011 Canonical Ltd. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os.path
from datetime import datetime, timedelta
from django.conf import settings
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
from oopstools.oops import dbsummaries
from oopstools.oops.helpers import parsedate
from oopstools.oops.models import Infestation, Oops, Report
from oopstools.oops.prefixloader import PrefixLoader
from oopstools.oops.oopsstore import OopsStore, OopsNotFound
def index(request):
# For any OOPS we search for:
# - the literal string
# - an upper() version of the string in case it was previously upper cased
# on insertion into the DB.
# - a lower() version of the string in case it wasn't upper cased but the
# user's reporting tool has upper cased it.
# - those three things with OOPS- prefixed, if they do not have that prefix
# already in case the url the user was given had had the OOPS- prefixed
# removed for some unknown reason, and the report has an OOPS- prefix in
# its id.
query_str = request.GET.get('oopsid', '')
oopsids = set([query_str])
oopsids.add(query_str.upper())
oopsids.add(query_str.lower())
if not query_str.upper().startswith('OOPS-'):
oopsids.update(map(lambda x:'OOPS-'+x, oopsids))
# Check each ID in both the database and filesystem
# (should maybe have an API option for this, instead of doing it manually?)
try:
oops = Oops.objects.get(oopsid__in=oopsids)
except Oops.DoesNotExist:
# Try to find the OOPS report in the filesystem.
oops = None
store = OopsStore(settings.OOPSDIR)
for oopsid in oopsids:
try:
oops = store.find_oops(oopsid)
break
except OopsNotFound:
pass
if oops and oops.exists():
tmpl = "oops.html"
data = {
'oops': oops
}
else:
tmpl = settings.INDEX_TEMPLATE
reports = Report.objects.filter(active=True)
data = {
'userdata': request.GET,
'reports': reports
}
return render_to_response(tmpl, dictionary=data)
def meta(request):
bug_number = request.POST.get('bug_number', '')
oopsid = request.POST.get('oopsid')
oops = Oops.objects.get(oopsid__exact=oopsid)
oops.oopsinfestation.bug = bug_number
oops.oopsinfestation.save()
return HttpResponseRedirect('/oops.py/?oopsid=%s' % oopsid)
def prefixloader(request):
prefixes = None
if request.method == "POST":
prefixloader = PrefixLoader(settings.LAZR_CONFIG)
prefixes = prefixloader.load_prefixes_into_database()
return render_to_response("prefixloader.html", dictionary={
"LAZR_CONFIG": settings.LAZR_CONFIG,
"prefixes": prefixes})
def get_recent_oops_info(report):
prefix_ids = list(report.prefixes.values_list('pk', flat=True))
recent_oopses = list(Oops.objects.raw("""
SELECT whatever.*, pos FROM (
select *, rank() OVER w AS pos
FROM oops_oops
WHERE "oops_oops"."prefix_id" = ANY(%s)
WINDOW w AS (PARTITION BY prefix_id ORDER BY date DESC)
) AS whatever
WHERE pos <= 50
ORDER BY date DESC
LIMIT 50;
""", [prefix_ids]))
infestation_pks = set([oops.oopsinfestation_id for oops in recent_oopses])
infestations = Infestation.objects.filter(id__in=infestation_pks).all()
exception_types = dict([(i.id, i.exception_type) for i in infestations])
return [(oops, exception_types[oops.oopsinfestation_id]) for oops in recent_oopses]
def report(request, report_name):
try:
r = Report.objects.get(name=report_name, active=True)
except Report.DoesNotExist:
raise Http404
else:
# Since reports are created by an external script, let's build URLs
# for the past ten days.
now = datetime.utcnow()
dates = []
for day in range(1, 11):
dates.append(now - timedelta(day))
recent = get_recent_oops_info(report)
data = {
'report': r,
'dates': dates,
'SUMMARY_URI': settings.SUMMARY_URI,
'recent': recent,
}
return render_to_response("report.html", dictionary=data)
def report_day_view(request, report_name, year, month, day):
filename = '-'.join([report_name, year, month, day]) + '.html'
# Try to find out if the report exists already.
if os.path.exists(os.path.join(settings.SUMMARY_DIR, filename)):
url = settings.SUMMARY_URI + '/' + filename
return HttpResponseRedirect(url)
else:
# Build it dynamically. This might take some time...
try:
report = Report.objects.get(name=report_name, active=True)
except Report.DoesNotExist:
raise Http404
else:
summary_class = getattr(dbsummaries, report.get_summary_display())
prefixes = [prefix.value for prefix in report.prefixes.all()]
start = end = parsedate("-".join([year, month, day]))
# XXX Unpack the data needed from the summary object to avoid
# doing processing in the template.
# There's probably a better way of doing this.
summary = summary_class(start, end, prefixes)
durations_section = summary.get_section_by_id('durations')
stmt_counts_section = summary.get_section_by_id(
'statement-counts')
timeout_counts = summary.get_section_by_id(
'time-out-counts-by-page-id')
data = {
'ROOT_URL': settings.ROOT_URL,
'summary': summary,
'durations': durations_section,
'stmt_counts': stmt_counts_section,
'timeout_counts': timeout_counts
}
return render_to_response("summary.html", dictionary=data)
|