Download:
child 6:3262fb214544
parent 4:69b4a7343f90
5:eaa6df85550a
Anton Shestakov <av6@dwimlabs.net>, Mon, 13 Jun 2016 11:14:12 +0800
incoming: parse checker output and store in a db

3 файлов изменено, 139 вставок(+), 0 удалений(-) [+]
candolint/models.py file | annotate | diff | comparison | revisions
incoming.py file | annotate | diff | comparison | revisions
requirements.txt file | annotate | diff | comparison | revisions
--- a/candolint/models.py Mon Jun 13 11:10:56 2016 +0800
+++ b/candolint/models.py Mon Jun 13 11:14:12 2016 +0800
@@ -8,6 +8,24 @@
class Meta:
database = database
+ @classmethod
+ def create_or_get(cls, **kwargs):
+ try:
+ with cls._meta.database.atomic():
+ return cls.create(**kwargs), True
+ except pw.IntegrityError:
+ # a variation on https://github.com/coleifer/peewee/pull/681
+ query = []
+ compound_unique = set()
+ for field_names, unique in cls._meta.indexes:
+ if unique:
+ compound_unique.update(field_names)
+ for field_name, value in kwargs.items():
+ field = getattr(cls, field_name)
+ if field.unique or field.primary_key or field_name in compound_unique:
+ query.append(field == value)
+ return cls.get(*query), False
+
class Project(BaseModel):
url = pw.CharField(unique=True)
--- a/incoming.py Mon Jun 13 11:10:56 2016 +0800
+++ b/incoming.py Mon Jun 13 11:14:12 2016 +0800
@@ -1,15 +1,135 @@
#!/usr/bin/env python
+import fileinput
+import logging
import os
+import re
+from datetime import datetime
+from urlparse import urlparse
+
+from tornado.escape import json_encode
+
from candolint.models import database, Project, Change, Check
rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x))
+def parse_timestamp(value):
+ return datetime.strptime(value, '%Y-%m-%dT%H:%M:%S+00:00')
+
+
+def insert_check(lines):
+ text = ''.join(lines)
+
+ meta_prefix = '# C&O '
+
+ result = []
+ errors = 0
+ warnings = 0
+ url = None
+ rev = None
+ node = None
+ branch = None
+ date = None
+ author = None
+ message = None
+ success = True
+ started = None
+ finished = None
+
+ for line in lines:
+ cls = None
+
+ if line.startswith(meta_prefix):
+ cls = 'meta'
+
+ rest = line[len(meta_prefix):]
+
+ m = re.match('^task: (\w+)$', rest)
+ if m is not None:
+ cls = 'task'
+
+ m = re.match('^job failed$', rest)
+ if m is not None:
+ success = False
+
+ m = re.match('^job (started|finished): ([\dT:+-]+)$', rest)
+ if m is not None:
+ if m.group(1) == 'started':
+ started = parse_timestamp(m.group(2))
+ elif m.group(1) == 'finished':
+ finished = parse_timestamp(m.group(2))
+
+ m = re.match('^project URL: (\S+)$', rest)
+ if m is not None:
+ url = m.group(1)
+
+ m = re.match('^commit: (\d+):(\w+) (\w+)$', rest)
+ if m is not None:
+ rev = m.group(1)
+ node = m.group(2)
+ branch = m.group(3)
+
+ m = re.match('^commit date: (.+)$', rest)
+ if m is not None:
+ date = m.group(1)
+
+ m = re.match('^commit author: (.+)$', rest)
+ if m is not None:
+ author = m.group(1)
+
+ m = re.match('^commit message: (.+)$', rest)
+ if m is not None:
+ message = m.group(1)
+
+ result.append((cls, line))
+
+ parsed = urlparse(url)
+ domain = parsed.hostname
+ parts = [part for part in parsed.path.split('/') if part]
+ if len(parts) > 1:
+ user, name = parts[-2:]
+ else:
+ user = None
+ name = parts[0]
+
+ with database.transaction():
+ project, created = Project.create_or_get(
+ url=url,
+ domain=domain,
+ user=user,
+ name=name)
+
+ change, created = Change.create_or_get(
+ rev=rev,
+ node=node,
+ branch=branch,
+ date=date,
+ author=author,
+ message=message,
+ project=project)
+
+ Check.create(
+ ordinal=Check.select().where(Check.project == project).count() + 1,
+ errors=errors,
+ warnings=warnings,
+ raw=text,
+ lines=json_encode(result),
+ success=success,
+ started=started,
+ finished=finished,
+ project=project,
+ change=change)
+
+
def main():
database.init(rel('database.sqlite'))
database.connect()
database.create_tables([Project, Change, Check], safe=True)
+ logger = logging.getLogger('peewee')
+ logger.setLevel(logging.DEBUG)
+ logger.addHandler(logging.StreamHandler())
+ insert_check(list(fileinput.input()))
database.close()
--- a/requirements.txt Mon Jun 13 11:10:56 2016 +0800
+++ b/requirements.txt Mon Jun 13 11:14:12 2016 +0800
@@ -1,2 +1,3 @@
peewee==2.8.1
PyYAML==3.11
+tornado==4.3