diff --git a/dashboard/static/css/style.css b/dashboard/static/css/style.css
index 241ebdfef..987fd0423 100644
--- a/dashboard/static/css/style.css
+++ b/dashboard/static/css/style.css
@@ -1,7 +1,6 @@
html, body {
font-family: 'PT Sans', arial, sans-serif;
font-size: 14px;
- background: url(../images/osstats_tile.jpg) repeat-x;
height: 100%;
color: #41454d;
margin: 0;
diff --git a/dashboard/templates/engineer_details.html b/dashboard/templates/engineer_details.html
index d78d5d307..3fb0ff1b4 100644
--- a/dashboard/templates/engineer_details.html
+++ b/dashboard/templates/engineer_details.html
@@ -33,6 +33,9 @@
{{ rec.date|datetimeformat }} to {{ rec.module }}
+ {% if rec.correction_comment %}
+
Commit corrected: {{ rec.correction_comment }}
+ {% endif %}
{{ rec.subject }}
{{ rec|commit_message|safe }}
+ {{ rec.lines_added }}
diff --git a/dashboard/templates/module_details.html b/dashboard/templates/module_details.html
index fde67a361..f14a93453 100644
--- a/dashboard/templates/module_details.html
+++ b/dashboard/templates/module_details.html
@@ -56,6 +56,9 @@
{{ rec.date|datetimeformat }}
+ {% if rec.correction_comment %}
+
Commit corrected: {{ rec.correction_comment }}
+ {% endif %}
{{ rec.subject }}
{{ rec|commit_message|safe }}
+ {{ rec.lines_added }}
diff --git a/etc/corrections.json b/etc/corrections.json
index 9d73def90..b05476962 100644
--- a/etc/corrections.json
+++ b/etc/corrections.json
@@ -2,7 +2,7 @@
"corrections": [
{
"commit_id": "ee3fe4e836ca1c81e50a8324a9b5f982de4fa97f",
- "correction_comment": "Rename of Quantum to Neutron",
+ "correction_comment": "Reset LOC to 0",
"lines_added": 0,
"lines_deleted": 0
}
diff --git a/etc/stackalytics.conf b/etc/stackalytics.conf
index a4fc9e401..fc08afb8b 100644
--- a/etc/stackalytics.conf
+++ b/etc/stackalytics.conf
@@ -6,7 +6,7 @@
# default-data = /etc/stackalytics/default_data.json
# The folder that holds all project sources to analyze
-# sources_root = /var/run/stackalytics
+# sources_root = /var/local/stackalytics
# Runtime storage URI
# runtime_storage_uri = memcached://127.0.0.1:11211
@@ -22,3 +22,6 @@
# Port where dashboard listens on
# listen_port = 8080
+
+# The address of file with corrections data
+# corrections-uri = https://raw.github.com/stackforge/stackalytics/master/etc/corrections.json
diff --git a/stackalytics/processor/config.py b/stackalytics/processor/config.py
index 068cbabe2..6517ee0bb 100644
--- a/stackalytics/processor/config.py
+++ b/stackalytics/processor/config.py
@@ -36,4 +36,8 @@ OPTS = [
help='The address dashboard listens on'),
cfg.IntOpt('listen-port', default=8080,
help='The port dashboard listens on'),
+ cfg.StrOpt('corrections-uri',
+ default=('https://raw.github.com/stackforge/stackalytics/'
+ 'master/etc/corrections.json'),
+ help='The address of file with corrections data'),
]
diff --git a/stackalytics/processor/main.py b/stackalytics/processor/main.py
index fdaa49a1a..35ba96b42 100644
--- a/stackalytics/processor/main.py
+++ b/stackalytics/processor/main.py
@@ -12,10 +12,12 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+import json
from oslo.config import cfg
import psutil
from psutil import _error
+import urllib2
from stackalytics.openstack.common import log as logging
from stackalytics.processor import commit_processor
@@ -84,6 +86,13 @@ def update_repos(runtime_storage, persistent_storage):
process_repo(repo, runtime_storage, processor)
+def apply_corrections(uri, runtime_storage_inst):
+ corrections_fd = urllib2.urlopen(uri)
+ raw = corrections_fd.read()
+ corrections_fd.close()
+ runtime_storage_inst.apply_corrections(json.loads(raw)['corrections'])
+
+
def main():
# init conf and logging
conf = cfg.CONF
@@ -111,6 +120,8 @@ def main():
update_repos(runtime_storage_inst, persistent_storage_inst)
+ apply_corrections(cfg.CONF.corrections_uri, runtime_storage_inst)
+
if __name__ == '__main__':
main()
diff --git a/stackalytics/processor/runtime_storage.py b/stackalytics/processor/runtime_storage.py
index 839fa8451..f5d2ca9ba 100644
--- a/stackalytics/processor/runtime_storage.py
+++ b/stackalytics/processor/runtime_storage.py
@@ -34,6 +34,9 @@ class RuntimeStorage(object):
def set_records(self, records_iterator):
pass
+ def apply_corrections(self, corrections_iterator):
+ pass
+
def get_head_commit_id(self, uri, branch):
pass
@@ -65,12 +68,10 @@ class MemcachedStorage(RuntimeStorage):
if record['commit_id'] in self.commit_id_index:
# update
record_id = self.commit_id_index[record['commit_id']]
- old_record = self.memcached.get(
- self._get_record_name(record_id))
- old_record['branches'] |= record['branches']
+ original = self.memcached.get(self._get_record_name(record_id))
+ original['branches'] |= record['branches']
LOG.debug('Update record %s' % record)
- self.memcached.set(self._get_record_name(record_id),
- old_record)
+ self.memcached.set(self._get_record_name(record_id), original)
else:
# insert record
record_id = self._get_record_count()
@@ -81,6 +82,24 @@ class MemcachedStorage(RuntimeStorage):
self._commit_update(record_id)
+ def apply_corrections(self, corrections_iterator):
+ for correction in corrections_iterator:
+ if correction['commit_id'] not in self.commit_id_index:
+ continue
+
+ record_id = self.commit_id_index[correction['commit_id']]
+ original = self.memcached.get(self._get_record_name(record_id))
+ need_update = False
+
+ for field, value in correction.iteritems():
+ if (field not in original) or (original[field] != value):
+ need_update = True
+ original[field] = value
+
+ if need_update:
+ self.memcached.set(self._get_record_name(record_id), original)
+ self._commit_update(record_id)
+
def get_head_commit_id(self, uri, branch):
key = str(urllib.quote_plus(uri) + ':' + branch)
return self.memcached.get(key)