diff --git a/dashboard/decorators.py b/dashboard/decorators.py
index b45bb92e1..a674407c9 100644
--- a/dashboard/decorators.py
+++ b/dashboard/decorators.py
@@ -140,9 +140,9 @@ def aggregate_filter():
positive = 0
mark_distribution = []
- for key in ['-2', '-1', '1', '2']:
+ for key in [-2, -1, 1, 2]:
if key in record:
- if key in ['1', '2']:
+ if key in [1, 2]:
positive += record[key]
mark_distribution.append(str(record[key]))
else:
diff --git a/dashboard/memory_storage.py b/dashboard/memory_storage.py
index a201a2cd7..e01537452 100644
--- a/dashboard/memory_storage.py
+++ b/dashboard/memory_storage.py
@@ -130,7 +130,7 @@ class CachedMemoryStorage(MemoryStorage):
def get_original_company_name(self, company_name):
normalized = company_name.lower()
if normalized not in self.company_name_mapping:
- raise Exception('Unknown company name %s' % company_name)
+ return normalized
return self.company_name_mapping[normalized]
def get_companies(self):
diff --git a/dashboard/reports.py b/dashboard/reports.py
index 17e331f9d..6600be583 100644
--- a/dashboard/reports.py
+++ b/dashboard/reports.py
@@ -83,31 +83,24 @@ def open_reviews(module):
memory_storage_inst = vault.get_memory_storage()
time_now = int(time.time())
- review_marks = {}
- reviews = {}
+ module_id_index = vault.get_vault()['module_id_index']
+ module = module.lower()
+ if module in module_id_index:
+ modules = module_id_index[module]['modules']
+ else:
+ modules = [module]
- mark_ids = (memory_storage_inst.get_record_ids_by_modules([module]) &
- memory_storage_inst.get_record_ids_by_type('mark'))
-
- for mark in memory_storage_inst.get_records(mark_ids):
- review_id = mark['review_id']
- if review_id in review_marks:
- if mark['date'] > review_marks[review_id]['date']:
- review_marks[review_id] = mark
- else:
- review = memory_storage_inst.get_record_by_primary_key(review_id)
- if not review:
- continue # todo because we filter jenkins
- review_marks[review_id] = mark
- reviews[review_id] = review
+ review_ids = (memory_storage_inst.get_record_ids_by_modules(modules) &
+ memory_storage_inst.get_record_ids_by_type('review'))
waiting_on_reviewer = []
total_open = 0
- for review_id, mark in review_marks.iteritems():
- if reviews[review_id]['open']:
+
+ for review in memory_storage_inst.get_records(review_ids):
+ if review['status'] == 'NEW':
total_open += 1
- if mark['value'] in ['1', '2']:
- waiting_on_reviewer.append(reviews[review_id])
+ if review['value'] in [1, 2]:
+ waiting_on_reviewer.append(review)
return {
'module': module,
@@ -115,7 +108,7 @@ def open_reviews(module):
'waiting_on_reviewer': len(waiting_on_reviewer),
'waiting_on_submitter': total_open - len(waiting_on_reviewer),
'latest_revision': _process_stat(
- waiting_on_reviewer, 'lastUpdated', time_now),
+ waiting_on_reviewer, 'updated_on', time_now),
'first_revision': _process_stat(waiting_on_reviewer, 'date', time_now),
}
diff --git a/dashboard/static/css/style.css b/dashboard/static/css/style.css
index ab341a0b2..2335acc30 100644
--- a/dashboard/static/css/style.css
+++ b/dashboard/static/css/style.css
@@ -159,6 +159,12 @@ div#right_list_wrapper {
.message {
white-space: pre-wrap;
+ margin-top: 0.8em;
+}
+
+.label {
+ font-weight: bold;
+ line-height: 135%;
}
a[href^="https://blueprints"]:after {
diff --git a/dashboard/static/js/stackalytics-ui.js b/dashboard/static/js/stackalytics-ui.js
index 95a60658c..838b5dcea 100644
--- a/dashboard/static/js/stackalytics-ui.js
+++ b/dashboard/static/js/stackalytics-ui.js
@@ -181,6 +181,27 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
});
}
+function render_bar_chart(chart_id, chart_data) {
+ $.jqplot(chart_id, chart_data, {
+ seriesDefaults: {
+ renderer: $.jqplot.BarRenderer,
+ rendererOptions: {
+ barMargin: 1
+ },
+ pointLabels: {show: true}
+ },
+ axes: {
+ xaxis: {
+ renderer: $.jqplot.CategoryAxisRenderer,
+ label: "Age"
+ },
+ yaxis: {
+ label: "Count"
+ }
+ }
+ });
+}
+
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
diff --git a/dashboard/templates/overview.html b/dashboard/templates/overview.html
index 6b8d5d366..2cbcd2569 100644
--- a/dashboard/templates/overview.html
+++ b/dashboard/templates/overview.html
@@ -318,7 +318,7 @@
{% if show_module_profile %}
Module {{ module }}
-
+
{% endif %}
diff --git a/dashboard/templates/reports/base_report.html b/dashboard/templates/reports/base_report.html
new file mode 100644
index 000000000..8ccacfd4f
--- /dev/null
+++ b/dashboard/templates/reports/base_report.html
@@ -0,0 +1,91 @@
+
+
+
+ {% block title %}{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% block head %}{% endblock %}
+
+
+
+
+{% macro show_activity_log(activity) -%}
+
+Activity Log
+
+{% if not activity %}
+ No activity.
+{% endif %}
+{% for item in activity %}
+
+
 }})
+
+
+
{{ item.date_str}}
+
{{ item.author_name }} ({{ item.company_name }})
+ {% if item.record_type == "commit" %}
+
Commit “{{ item.subject }}”
+
{{ item.message | safe }}
+
+{{ item.lines_added }}
+ - {{ item.lines_deleted }}
+
+ {% if item.correction_comment %}
+
Commit corrected:
+ {{ item.correction_comment }}
+ {% endif %}
+ {% elif item.record_type == "mark" %}
+
Review “{{item.subject}}”
+
Patch submitted by {{ parent_author_link }}
+
+
+ {{item.description}}: {{item.value}}
+ {% elif item.record_type == "email" %}
+
Email “{{item.subject}}”
+ {% if item.body %}
+
{{ item.body|safe }}
+ {% endif %}
+ {% endif %}
+
+
+
+{% endfor %}
+
+{%- endmacro %}
+
+
+
+{% block body %}{% endblock %}
+
+
+
diff --git a/dashboard/templates/reports/blueprint_summary.html b/dashboard/templates/reports/blueprint_summary.html
index 9df4c8bc7..7b558761a 100644
--- a/dashboard/templates/reports/blueprint_summary.html
+++ b/dashboard/templates/reports/blueprint_summary.html
@@ -1,21 +1,10 @@
-
-
-
- {{ blueprint.title }}
-
-
-
-
+{% extends "reports/base_report.html" %}
+{% block title %}
+Blueprint {{ blueprint.title }} detailed report
+{% endblock %}
+
+{% block body %}
Blueprint “{{ blueprint.name }}”
Title: {{ blueprint.title }}
@@ -42,43 +31,6 @@
{{ blueprint.whiteboard }}
{% endif %}
-Activity Log
-{% if not activity %}
- No activities related to this blueprint.
-{% endif %}
-{% for item in activity %}
-
-
 }})
-
-
-
{{ item.date_str}}
-
{{ item.author_name }} ({{ item.company_name }})
- {% if item.record_type == "commit" %}
-
Commit “{{ item.subject }}”
-
{{ item.message | safe }}
-
+{{ item.lines_added }}
- - {{ item.lines_deleted }}
-
- {% if item.correction_comment %}
-
Commit corrected:
- {{ item.correction_comment }}
- {% endif %}
- {% elif item.record_type == "mark" %}
-
Review “{{item.subject}}”
-
Patch submitted by {{ parent_author_link }}
-
-
- {{item.description}}: {{item.value}}
- {% elif item.record_type == "email" %}
-
Email “{{item.subject}}”
- {% if item.body %}
-
{{ item.body|safe }}
- {% endif %}
- {% endif %}
-
-
-
-{% endfor %}
-
-
\ No newline at end of file
+{{ show_activity_log(activity) }}
+{% endblock %}
diff --git a/dashboard/templates/reports/open_reviews.html b/dashboard/templates/reports/open_reviews.html
index 1cb8c6eca..779f44fdf 100644
--- a/dashboard/templates/reports/open_reviews.html
+++ b/dashboard/templates/reports/open_reviews.html
@@ -1,87 +1,26 @@
-
-
-
- Open reviews report for {{ module }}
-
+{% extends "reports/base_report.html" %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+{% block title %}
+Open reviews report for {{ module }}
+{% endblock %}
+{% block head %}
+{% endblock %}
-
-
-
-
+{% block body %}
Open reviews for {{ module }}
-Summary:
+Summary
- Total open reviews: {{ total_open }}
- - Waiting on reviewer: {{ waiting_on_reviewer }}
- Waiting on submitter: {{ waiting_on_submitter }}
+ - Waiting on reviewer: {{ waiting_on_reviewer }}
{% if total_open %}
@@ -96,7 +35,7 @@
{% for item in latest_revision.reviews[:5] %}
- - {{ item.lastUpdated_age }} {{ item.url }} {{ item.subject }} by {{ item.author_name }} ({{ item.company_name }})
+ - {{ item.updated_on_age }} {{ item.url }} {{ item.subject }} by {{ item.author_name }} ({{ item.company_name }})
{% endfor %}
@@ -115,4 +54,5 @@
{% endfor %}
-{% endif %}
\ No newline at end of file
+{% endif %}
+{% endblock %}
diff --git a/dashboard/vault.py b/dashboard/vault.py
index d19053402..afa07b03f 100644
--- a/dashboard/vault.py
+++ b/dashboard/vault.py
@@ -127,7 +127,7 @@ def init_module_groups(vault):
module_group_name = module_group['module_group_name']
module_group_id = module_group_name.lower()
- module_id_index[module_group_name] = {
+ module_id_index[module_group_id] = {
'group': True,
'id': module_group_id,
'text': module_group_name,
diff --git a/dashboard/web.py b/dashboard/web.py
index 3c5e7acdb..8d8015480 100644
--- a/dashboard/web.py
+++ b/dashboard/web.py
@@ -170,7 +170,7 @@ def get_contribution_json(records):
commit_count += 1
loc += record['loc']
elif record['record_type'] == 'mark':
- marks[int(record['value'])] += 1
+ marks[record['value']] += 1
elif record['record_type'] == 'email':
email_count += 1
elif record['record_type'] == 'bpd':
diff --git a/etc/test_default_data.json b/etc/test_default_data.json
index 9c5a15089..e6156f615 100644
--- a/etc/test_default_data.json
+++ b/etc/test_default_data.json
@@ -16,7 +16,7 @@
]
},
{
- "launchpad_id": "openstack",
+ "launchpad_id": "jenkins",
"companies": [
{
"company_name": "*robots",
@@ -48,8 +48,8 @@
"domains": ["intel.com"]
},
{
- "domains": ["openstack.org"],
- "company_name": "OpenStack Foundation"
+ "domains": ["robots"],
+ "company_name": "*robots"
}
],
diff --git a/stackalytics/processor/record_processor.py b/stackalytics/processor/record_processor.py
index 6cafbebae..738448889 100644
--- a/stackalytics/processor/record_processor.py
+++ b/stackalytics/processor/record_processor.py
@@ -206,6 +206,20 @@ class RecordProcessor(object):
review['author_email'] = owner['email'].lower()
review['date'] = record['createdOn']
+ patch_sets = record.get('patchSets', [])
+ review['updated_on'] = review['date']
+ if patch_sets:
+ patch = patch_sets[-1]
+ if 'approvals' in patch:
+ review['value'] = min([int(p['value'])
+ for p in patch['approvals']])
+ review['updated_on'] = patch['approvals'][0]['grantedOn']
+ else:
+ review['updated_on'] = patch['createdOn']
+
+ if 'value' not in review:
+ review['value'] = 0
+
self._update_record_and_user(review)
yield review
@@ -220,13 +234,14 @@ class RecordProcessor(object):
for approval in patch['approvals']:
# copy everything and flatten user data
mark = dict([(k, v) for k, v in approval.iteritems()
- if k not in ['by', 'grantedOn']])
+ if k not in ['by', 'grantedOn', 'value']])
reviewer = approval['by']
if 'email' not in reviewer or 'username' not in reviewer:
continue # ignore
mark['record_type'] = 'mark'
+ mark['value'] = int(approval['value'])
mark['date'] = approval['grantedOn']
mark['primary_key'] = (record['id'] +
str(mark['date']) +