Commit b4bf105c by Kálmán Viktor

Merge branch 'master' into feature-request

Conflicts:
	circle/dashboard/static/dashboard/dashboard.less
parents 815d11ea f211db99
......@@ -12,7 +12,7 @@
],
"dependencies": {
"bootstrap": "~3.2.0",
"fontawesome": "~4.2.0",
"fontawesome": "~4.3.0",
"jquery": "~2.1.1",
"no-vnc": "*",
"jquery-knob": "~1.2.9",
......
......@@ -169,7 +169,8 @@ PIPELINE_COMPILERS = (
'pipeline.compilers.less.LessCompiler',
)
PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.slimit.SlimItCompressor'
# PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.slimit.SlimItCompressor'
PIPELINE_JS_COMPRESSOR = None
PIPELINE_DISABLE_WRAPPER = True
PIPELINE_LESS_ARGUMENTS = u'--include-path={}'.format(':'.join(STATICFILES_DIRS))
PIPELINE_CSS = {
......@@ -525,7 +526,7 @@ except:
AGENT_VERSION = None
LOCALE_PATHS = (join(SITE_ROOT, 'locale'), )
COMPANY_NAME = "BME IK 2014"
COMPANY_NAME = get_env_variable("COMPANY_NAME", "BME IK 2015")
graphite_host = environ.get("GRAPHITE_HOST", None)
graphite_port = environ.get("GRAPHITE_PORT", None)
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.core.management.base import BaseCommand
from common.management.commands.watch import LessUtils
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import subprocess
import os
import pyinotify
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from sys import exc_info
import logging
......
# -*- coding: utf-8 -*-
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from arrow import locales
class HungarianLocale(locales.Locale):
names = ['hu', 'HU']
past = '{0} ezelőtt'
future = '{0} múlva'
timeframes = {
'now': 'éppen most',
'seconds': {
'past': 'másodpercekkel',
'future': 'pár másodperc'},
'minute': {'past': 'egy perccel', 'future': 'egy perc'},
'minutes': {'past': '{0} perccel', 'future': '{0} perc'},
'hour': {'past': 'egy órával', 'future': 'egy óra'},
'hours': {'past': '{0} órával', 'future': '{0} óra'},
'day': {
'past': 'egy nappal',
'future': 'egy nap'
},
'days': {
'past': '{0} nappal',
'future': '{0} nap'
},
'month': {'past': 'egy hónappal', 'future': 'egy hónap'},
'months': {'past': '{0} hónappal', 'future': '{0} hónap'},
'year': {'past': 'egy évvel', 'future': 'egy év'},
'years': {'past': '{0} évvel', 'future': '{0} év'},
}
month_names = ['', 'Január', 'Február', 'Március', 'Április', 'Május',
'Június', 'Július', 'Augusztus', 'Szeptember',
'Október', 'November', 'December']
month_abbreviations = ['', 'Jan', 'Febr', 'Márc', 'Ápr', 'Máj', 'Jún',
'Júl', 'Aug', 'Szept', 'Okt', 'Nov', 'Dec']
day_names = ['', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek',
'Szombat', 'Vasárnap']
day_abbreviations = ['', 'Hét', 'Kedd', 'Szer', 'Csüt', 'Pént',
'Szom', 'Vas']
meridians = {
'am': 'de',
'pm': 'du',
'AM': 'DE',
'PM': 'DU',
}
def _format_timeframe(self, timeframe, delta):
form = self.timeframes[timeframe]
if isinstance(form, dict):
if delta > 0:
form = form['future']
else:
form = form['past']
delta = abs(delta)
return form.format(delta)
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import autocomplete_light
from django.contrib.auth.models import User
from django.utils.html import escape
......
......@@ -1607,11 +1607,16 @@ class DataStoreForm(ModelForm):
class DiskForm(ModelForm):
created = forms.DateTimeField()
modified = forms.DateTimeField()
def __init__(self, *args, **kwargs):
super(DiskForm, self).__init__(*args, **kwargs)
for k, v in self.fields.iteritems():
v.widget.attrs['readonly'] = True
self.fields['created'].initial = self.instance.created
self.fields['modified'].initial = self.instance.modified
class Meta:
model = Disk
......@@ -651,9 +651,11 @@ textarea[name="new_members"] {
padding-left: 28px;
}
.dashboard-profile-vm-list a, .dashboard-profile-vm-list a:hover {
text-decoration: none;
color: #555;
.dashboard-profile-vm-list, .dashboard-profile-group-list {
a, a:hover {
text-decoration: none;
color: #555;
}
}
#group-detail-user-table td:nth-child(2) a,
......@@ -1288,3 +1290,9 @@ textarea[name="new_members"] {
max-width: 500px;
height: 150px;
}
#disk-list-table {
td:last-child {
text-align: center;
}
}
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from os.path import splitext
import json
import logging
......
......@@ -350,4 +350,5 @@ class DiskListTable(Table):
fields = ("pk", "appliance", "filename", "size", "is_ready")
prefix = "disk-"
order_by = ("-pk", )
per_page = 65536
per_page = 15
empty_text = _("No disk found.")
{% load i18n %}
{% load hro %}
{% load arrowfilter %}
{% for n in page %}
<li class="notification-message" id="msg-{{n.id}}">
<span class="notification-message-subject">
{% if n.status == "new" %}<i class="fa fa-envelope-o"></i> {% endif %}
{{ n.subject|get_text:user }}
</span>
<span class="notification-message-date pull-right" title="{{n.created}}">
{{ n.created|timesince }}
<span class="notification-message-date pull-right" title="{{n.created}}" data-container="body">
{{ n.created|arrowfilter:LANGUAGE_CODE }}
</span>
<div style="clear: both;"></div>
<div class="notification-message-text">
......
{% load i18n %}
{% load hro %}
{% load arrowfilter %}
<div id="activity-timeline" class="timeline">
{% for a in activities %}
<div class="activity" data-activity-id="{{ a.pk }}">
......@@ -10,7 +11,8 @@
{{ a.readable_name.get_admin_text|capfirst }}
</strong>
{{ a.started|date:"Y-m-d H:i" }}{% if a.user %}, {{ a.user }}{% endif %}
<span title="{{ a.started }}">{{ a.started|arrowfilter:LANGUAGE_CODE }}</span>{% if a.user %}, {{ a.user }}{% endif %}
{% if a.children.count > 0 %}
<div class="sub-timeline">
{% for s in a.children.all %}
......@@ -21,7 +23,9 @@
</span>
&ndash;
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
<span title="{{ s.finished }}">
{{ s.finished|arrowfilter:LANGUAGE_CODE }}
</span>
{% else %}
<i class="fa fa-refresh fa-spin" class="sub-activity-loading-icon"></i>
{% endif %}
......
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block title-page %}{% trans "Notifications" %}{% endblock %}
{% block content %}
<div class="row">
......
......@@ -11,24 +11,28 @@
<div class="col-md-{% if perms.auth.change_user %}8{% else %}12{% endif %}">
<div class="panel panel-default">
<div class="panel-heading">
{% if request.user.is_superuser %}
<a href="{{ login_token }}"
class="pull-right btn btn-danger btn-xs"
title="{% trans "Log in as this user. Recommended to open in an incognito window." %}">
{% trans "Login as this user" %}</a>
{% endif %}
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.user-list" %}">{% trans "Back" %}</a>
<div class="pull-right">
{% if request.user.is_superuser %}
<a href="{{ login_token }}" class="btn btn-danger btn-xs"
title="{% trans "Log in as this user. Recommended to open in an incognito window." %}">
<i class="fa fa-user-secret"></i>
{% trans "Login as this user" %}
</a>
{% endif %}
<a class="btn btn-default btn-xs" href="{% url "dashboard.views.user-list" %}">
{% trans "Back" %}</a>
</div>
<h3 class="no-margin">
<i class="fa fa-user"></i>
{% include "dashboard/_display-name.html" with user=profile show_org=True %}
</h3>
</div>
<div class="panel-body">
<div>
<div class="" style="float: left">
<div class="row">
<div class="col-sm-4">
<img id="dashboard-profile-avatar" src="{{ avatar_url }}" class="img-rounded"/>
</div>
<div class="" style="padding-left: 215px;">
<div class="col-sm-8">
<p>{% trans "Username" %}: {{ profile.username }}</p>
<p>{% trans "Organization ID" %}: {{ profile.profile.org_id|default:"-" }}</p>
<p>{% trans "First name" %}: {{ profile.first_name|default:"-" }}</p>
......@@ -48,7 +52,6 @@
<a href="{% url "dashboard.views.profile-preferences" %}">{% trans "Change my preferences" %}</a>
{% endif %}
</div>
<div class="clearfix"></div>
</div>
{% if perm_group_list %}
......@@ -57,11 +60,11 @@
<i class="fa fa-group"></i> {% trans "Groups" %}
</h4>
<ul class="dashboard-profile-group-list">
{% for g in groups %}
<li>{{ g.name }}</li>
{% for g in groups %}
<li><a href="{{ g.profile.get_absolute_url }}">{{ g.name }}</a></li>
{% empty %}
{% trans "This user is not in any group." %}
{% endfor %}
{% endfor %}
</ul>
{% endif %}
......
......@@ -52,7 +52,9 @@
<small>{% trans "image files without disk object in the database" %}</small>
</h3>
{% for o in orphan_disks %}
{{ o }}
<p>
{{ o }}
</p>
{% empty %}
{% trans "None" %}
{% endfor %}
......@@ -68,6 +70,33 @@
<h3 class="no-margin"><i class="fa fa-file"></i> {% trans "Disks" %}</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-9">
<ul class="nav nav-pills" style="margin: 5px 0 20px 0;">
<li class="disabled"><a href="#">{% trans "Filter by type" %}</a></li>
<li {% if not request.GET.filter %} class="active"{% endif %}>
<a href="{{ request.path }}?s={{ request.GET.s }}">{% trans "ALL" %}</a>
</li>
{% for f in filter_names %}
<li{% if request.GET.filter == f.0 %} class="active"{% endif %}>
<a href="?filter={{ f.0 }}&s={{ request.GET.s }}">{{ f.1|capfirst }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="col-md-3">
<form action="" method="GET" id="network-host-list-form">
<div class="input-group">
<input type="text" name="s" class="form-control"
value="{{ request.GET.s }}" placeholder="{% trans "Search..." %}"/>
<span class="input-group-btn">
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
</span>
<input type="hidden" name="filter" value="{{ request.GET.filter }}"/>
</div>
</form>
</div>
</div><!-- .row -->
<div class="table-responsive">
{% render_table disk_table %}
</div>
......
{{ record.created|date }}
<br />
{{ record.created|time }}
{% load arrowfilter %}
<span title="{{ record.created }}">
{{ record.created|arrowfilter:LANGUAGE_CODE }}
</span>
{% load i18n %}
{% load hro %}
{% load arrowfilter %}
<div id="activity-timeline" class="timeline">
{% for a in activities %}
......@@ -18,7 +19,7 @@
- {{ a.percentage }}%
{% endif %}
</strong>
{% endspaceless %}{% if a.times < 2%} {{ a.started|date:"Y-m-d H:i" }}{% endif %}{% if a.user %},
{% endspaceless %}{% if a.times < 2 %} <span title="{{ a.started }}">{{ a.started|arrowfilter:LANGUAGE_CODE }}</span>{% endif %}{% if a.user %},
<a class="no-style-link" href="{% url "dashboard.views.profile" username=a.user.username %}">
{% include "dashboard/_display-name.html" with user=a.user show_org=True %}
</a>
......@@ -40,7 +41,9 @@
<a href="{{ s.get_absolute_url }}">
{{ s.readable_name|get_text:user|capfirst }}</a></span> &ndash;
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
<span title="{{ s.finished }}">
{{ s.finished|arrowfilter:LANGUAGE_CODE }}
</span>
{% else %}
<i class="fa fa-refresh fa-spin" class="sub-activity-loading-icon"></i>
{% endif %}
......
{% load i18n %}
{% load arrowfilter %}
<div class="row">
<div class="col-md-4">
<dl id="home_name_and_description">
......@@ -70,13 +71,13 @@
<dt>{% trans "Suspended at:" %}</dt>
<dd>
<span title="{{ instance.time_of_suspend }}">
<i class="fa fa-moon-o"></i> {{ instance.time_of_suspend|timeuntil }}
<i class="fa fa-moon-o"></i> {{ instance.time_of_suspend|arrowfilter:LANGUAGE_CODE }}
</span>
</dd>
<dt>{% trans "Destroyed at:" %}</dt>
<dd>
<span title="{{ instance.time_of_delete }}">
<i class="fa fa-times"></i> {{ instance.time_of_delete|timeuntil }}
<i class="fa fa-times"></i> {{ instance.time_of_delete|arrowfilter:LANGUAGE_CODE }}
</span>
</dd>
</dl>
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.template import Library
import arrow
from dashboard.arrow_local import HungarianLocale
for name in HungarianLocale.names:
arrow.locales._locales[name] = HungarianLocale
register = Library()
@register.filter
def arrowfilter(date, language='en'):
if not date:
return ''
adate = arrow.get(date)
return adate.humanize(locale=language)
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.template import Library
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django import template
register = template.Library()
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import unittest
from mock import patch, MagicMock
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
......
......@@ -61,8 +61,7 @@ class GroupCodeMixin(object):
state = StateCache(request.session)
conf = get_config(None, request)
client = Saml2Client(conf, state_cache=state,
identity_cache=IdentityCache(request.session),
logger=logger)
identity_cache=IdentityCache(request.session))
subject_id = _get_subject_id(request.session)
identity = client.users.get_identity(subject_id,
check_not_on_or_after=False)
......
......@@ -16,13 +16,16 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals, absolute_import
from django.views.generic import UpdateView
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.views.generic import UpdateView
from sizefield.utils import filesizeformat
from braces.views import SuperuserRequiredMixin
from sizefield.utils import filesizeformat
from common.models import WorkerNotFound
from storage.models import DataStore, Disk
from ..tables import DiskListTable
from ..forms import DataStoreForm, DiskForm
......@@ -40,15 +43,53 @@ class StorageDetail(SuperuserRequiredMixin, UpdateView):
context = super(StorageDetail, self).get_context_data(**kwargs)
ds = self.get_object()
context['stats'] = self._get_stats()
context['missing_disks'] = ds.get_missing_disks()
context['orphan_disks'] = ds.get_orphan_disks()
qs = Disk.objects.filter(datastore=ds, destroyed=None)
try:
context['stats'] = self._get_stats()
context['missing_disks'] = ds.get_missing_disks()
context['orphan_disks'] = ds.get_orphan_disks()
except WorkerNotFound:
messages.error(self.request, _("The DataStore is offline."))
context['disk_table'] = DiskListTable(
qs, request=self.request,
template="django_tables2/table_no_page.html")
self.get_table_data(), request=self.request,
template="django_tables2/with_pagination.html")
context['filter_names'] = (
('vm', _("virtual machine")),
('template', _("template")),
('none', _("none")),
)
return context
def get_table_data(self):
ds = self.get_object()
qs = Disk.objects.filter(datastore=ds, destroyed=None)
filter_name = self.request.GET.get("filter")
search = self.request.GET.get("s")
filter_queries = {
'vm': {
'instance_set__isnull': False,
},
'template': {
'template_set__isnull': False,
},
'none': {
'template_set__isnull': True,
'instance_set__isnull': True,
}
}
if filter_name:
qs = qs.filter(**filter_queries.get(filter_name, {}))
if search:
search = search.strip()
qs = qs.filter(Q(name__icontains=search) |
Q(filename__icontains=search))
return qs
def _get_stats(self):
stats = self.object.get_statistics()
free_space = int(stats['free_space'])
......@@ -72,3 +113,6 @@ class DiskDetail(SuperuserRequiredMixin, UpdateView):
model = Disk
form_class = DiskForm
template_name = "dashboard/storage/disk.html"
def form_valid(self, form):
pass
#!/bin/echo Usage: fab --list -f
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import contextlib
import datetime
......@@ -46,6 +64,14 @@ def bower(component=None):
@roles('portal')
def flake8():
"Run portal tests"
with _workon("circle"), cd("~/circle/circle"):
run("flake8 . --exclude=migrations,bower_components,"
"south_migrations,static_collected --max-complexity 12")
@roles('portal')
def migrate():
"Run db migrations"
with _workon("circle"), cd("~/circle/circle"):
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#