pax_global_header 0000666 0000000 0000000 00000000064 12240152740 0014507 g ustar 00root root 0000000 0000000 52 comment=e67366887fe6df96d33ccef18c937edfcaae8a35 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/ 0000775 0000000 0000000 00000000000 12240152740 0026167 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/.gitignore 0000664 0000000 0000000 00000000325 12240152740 0030157 0 ustar 00root root 0000000 0000000 # Python bytecode: *.py[co] # Packaging files: *.egg* # Editor temp files: *.swp *~ # Sphinx docs: build _build # SQLite3 database files: *.db # Logs: *.log .ropeproject celerybeat-schedule .coverage *,cover CONTRIBUTORS.txt 0000664 0000000 0000000 00000000141 12240152740 0030602 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35 Adam Dudas Bence Danyi Daniel Bach Gergo Nagy Imre Szeberenyi Mate Ory Sandor Guba Viktor Kalman cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/LICENSE.txt 0000664 0000000 0000000 00000000206 12240152740 0030010 0 ustar 00root root 0000000 0000000 Copyright (c) 2012--2013 Budapest University of Technology and Economics (BME-IK), and contributors. [SOME OPEN SOURCE LICENSE HERE] cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/README.rst 0000664 0000000 0000000 00000000163 12240152740 0027656 0 ustar 00root root 0000000 0000000 ============= cirecle-cloud ============= This is the Django based controller and web portal of the CIRCLE Cloud. cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/ 0000775 0000000 0000000 00000000000 12240152740 0027430 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000000000 12240152740 0031450 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/ 0000775 0000000 0000000 00000000000 12240152740 0030167 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000000000 12240152740 0032207 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl management/ 0000775 0000000 0000000 00000000000 12240152740 0032224 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl __init__.py 0000664 0000000 0000000 00000005267 12240152740 0034347 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/management """ Creates Levels for all installed apps that have levels. """ from django.db.models import get_models, signals from django.db import DEFAULT_DB_ALIAS from django.core.exceptions import ImproperlyConfigured from ..models import Level, AclBase def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS, **kwargs): """Create and set the weights of the configured Levels. Based on django.contrib.auth.management.__init__.create_permissions""" # if not router.allow_migrate(db, auth_app.Permission): # return from django.contrib.contenttypes.models import ContentType app_models = [k for k in get_models(app) if AclBase in k.__bases__] print "Creating levels for models: %s." % ", ".join([m.__name__ for m in app_models]) # This will hold the levels we're looking for as # (content_type, (codename, name)) searched_levels = list() level_weights = list() # The codenames and ctypes that should exist. ctypes = set() for klass in app_models: # Force looking up the content types in the current database # before creating foreign keys to them. ctype = ContentType.objects.db_manager(db).get_for_model(klass) ctypes.add(ctype) weight = 0 try: for codename, name in klass.ACL_LEVELS: searched_levels.append((ctype, (codename, name))) level_weights.append((ctype, codename, weight)) weight += 1 except AttributeError: raise ImproperlyConfigured( "Class %s doesn't have ACL_LEVELS attribute." % klass) # Find all the Levels that have a content_type for a model we're # looking for. We don't need to check for codenames since we already have # a list of the ones we're going to create. all_levels = set(Level.objects.using(db).filter( content_type__in=ctypes, ).values_list( "content_type", "codename" )) levels = [ Level(codename=codename, name=name, content_type=ctype) for ctype, (codename, name) in searched_levels if (ctype.pk, codename) not in all_levels ] Level.objects.using(db).bulk_create(levels) if verbosity >= 2: print("Adding levels [%s]." % ", ".join(levels)) print("Searched: [%s]." % ", ".join([unicode(l) for l in searched_levels])) print("All: [%s]." % ", ".join([unicode(l) for l in all_levels])) # set weights for ctype, codename, weight in level_weights: Level.objects.filter(codename=codename, content_type=ctype).update(weight=weight) signals.post_syncdb.connect( create_levels, dispatch_uid="circle.acl.management.create_levels") commands/ 0000775 0000000 0000000 00000000000 12240152740 0034025 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/management __init__.py 0000664 0000000 0000000 00000000000 12240152740 0036124 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/management/commands update_levels.py 0000664 0000000 0000000 00000000353 12240152740 0037234 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/management/commands from django.core.management.base import BaseCommand from .. import create_levels class Command(BaseCommand): args = '' help = 'Regenerates Levels' def handle(self, *args, **options): create_levels(None, None, 3) models.py 0000664 0000000 0000000 00000013671 12240152740 0031755 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl import logging from django.contrib.auth.models import User, Group from django.contrib.contenttypes.generic import ( GenericForeignKey, GenericRelation ) from django.contrib.contenttypes.models import ContentType from django.db.models import ( ManyToManyField, ForeignKey, CharField, Model, IntegerField ) logger = logging.getLogger(__name__) class Level(Model): """Definition of a permission level. Instances are automatically populated based on AclBase.""" name = CharField('name', max_length=50) content_type = ForeignKey(ContentType) codename = CharField('codename', max_length=100) weight = IntegerField('weight', null=True) def __unicode__(self): return "<%s/%s>" % (unicode(self.content_type), self.name) class Meta: unique_together = (('content_type', 'codename'), # ('content_type', 'weight'), # TODO find a way of temp. disabling this constr. ) class ObjectLevel(Model): """Permission level for a specific object.""" level = ForeignKey(Level) content_type = ForeignKey(ContentType) object_id = CharField(max_length=255) content_object = GenericForeignKey() users = ManyToManyField(User) groups = ManyToManyField(Group) def __unicode__(self): return "<%s: %s>" % (unicode(self.content_object), unicode(self.level)) class Meta: unique_together = (('content_type', 'object_id', 'level'),) class AclBase(Model): """Define permission levels for Users/Groups per object.""" object_level_set = GenericRelation(ObjectLevel) @classmethod def get_level_object(cls, level): """Get Level object for this model by codename.""" ct = ContentType.objects.get_for_model(cls) return Level.objects.get(codename=level, content_type=ct) def set_level(self, whom, level): """Set level of object for a user or group. :param whom: user or group the level is set for :type whom: User or Group :param level: codename of level to set :type level: Level or str or unicode """ if isinstance(whom, User): self.set_user_level(whom, level) elif isinstance(whom, Group): self.set_group_level(whom, level) else: raise AttributeError('"whom" must be a User or Group object.') def set_user_level(self, user, level): """Set level of object for a user. :param whom: user the level is set for :type whom: User :param level: codename of level to set :type level: Level or str or unicode """ logger.info('%s.set_user_level(%s, %s) called', *[unicode(p) for p in [self, user, level]]) if isinstance(level, basestring): level = self.get_level_object(level) if not self.object_level_set.filter(level_id=level.pk).exists(): self.object_level_set.create(level=level) for i in self.object_level_set.all(): if i.level_id != level.pk: i.users.remove(user) else: i.users.add(user) i.save() def set_group_level(self, group, level): """Set level of object for a user. :param whom: user the level is set for :type whom: User or unicode or str :param level: codename of level to set :type level: str or unicode """ logger.info('%s.set_group_level(%s, %s) called', *[unicode(p) for p in [self, group, level]]) if isinstance(level, basestring): level = self.get_level_object(level) #self.object_level_set.get_or_create(level=level, content_object=self) if not self.object_level_set.filter(level_id=level.pk).exists(): self.object_level_set.create(level=level) for i in self.object_level_set.all(): if i.level_id != level.pk: i.groups.remove(group) else: i.groups.add(group) i.save() def has_level(self, user, level, group_also=True): logger.debug('%s.has_level(%s, %s, %s) called', *[unicode(p) for p in [self, user, level, group_also]]) if getattr(user, 'is_superuser', False): logger.debug('- superuser granted') return True if isinstance(level, basestring): level = self.get_level_object(level) logger.debug("- level set by str: %s", unicode(level)) object_levels = self.object_level_set.filter( level__weight__gte=level.weight).all() groups = user.groups.values_list('id', flat=True) if group_also else [] for i in object_levels: if i.users.filter(pk=user.pk).exists(): return True if group_also and i.groups.filter(pk__in=groups).exists(): return True return False def get_users_with_level(self): logger.debug('%s.get_users_with_level() called', unicode(self)) object_levels = (self.object_level_set.select_related( 'users', 'level').all()) users = [] for object_level in object_levels: name = object_level.level.codename olusers = object_level.users.all() users.extend([(u, name) for u in olusers]) logger.debug('- %s: %s' % (name, [u.username for u in olusers])) return users def get_groups_with_level(self): logger.debug('%s.get_groups_with_level() called', unicode(self)) object_levels = (self.object_level_set.select_related( 'groups', 'level').all()) groups = [] for object_level in object_levels: name = object_level.level.codename olgroups = object_level.groups.all() groups.extend([(g, name) for g in olgroups]) logger.debug('- %s: %s' % (name, [g.name for g in olgroups])) return groups class Meta: abstract = True tests/ 0000775 0000000 0000000 00000000000 12240152740 0031252 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl __init__.py 0000664 0000000 0000000 00000000000 12240152740 0033351 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/tests models.py 0000664 0000000 0000000 00000000623 12240152740 0033110 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/tests from django.db.models import TextField from ..models import AclBase class TestModel(AclBase): normal_field = TextField() ACL_LEVELS = ( ('alfa', 'Alfa'), ('bravo', 'Bravo'), ('charlie', 'Charlie'), ) class Test2Model(AclBase): normal2_field = TextField() ACL_LEVELS = ( ('one', 'One'), ('two', 'Two'), ('three', 'Three'), ) test_acl.py 0000664 0000000 0000000 00000013441 12240152740 0033425 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl/tests from django.test import TestCase from django.contrib.auth.models import User, Group, AnonymousUser from ..models import ObjectLevel from .models import TestModel, Test2Model class AclUserTest(TestCase): def setUp(self): self.u1 = User.objects.create(username='user1') self.u2 = User.objects.create(username='user2', is_staff=True) self.us = User.objects.create(username='superuser', is_superuser=True) self.g1 = Group.objects.create(name='group1') self.g1.user_set.add(self.u1) self.g1.user_set.add(self.u2) self.g1.save() def test_level_exists(self): for codename, name in TestModel.ACL_LEVELS: level = TestModel.get_level_object(codename) self.assertEqual(level.codename, codename) for codename, name in Test2Model.ACL_LEVELS: level = Test2Model.get_level_object(codename) self.assertEqual(level.codename, codename) def test_lowest_user_level(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa', False)) self.assertFalse(i.has_level(self.u1, 'bravo', False)) i.set_level(self.u1, 'alfa') i.set_level(self.g1, 'bravo') self.assertTrue(i.has_level(self.u1, 'alfa', False)) self.assertFalse(i.has_level(self.u1, 'bravo', False)) def test_anonymous_user_level(self): i = TestModel.objects.create(normal_field='Hello') anon = AnonymousUser() self.assertFalse(i.has_level(anon, 'alfa')) self.assertFalse(i.has_level(anon, 'bravo')) def test_middle_user_level(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) i.set_level(self.u1, 'bravo') self.assertTrue(i.has_level(self.u1, 'alfa')) self.assertTrue(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) def test_level_set_twice_same(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) i.set_level(self.u1, 'bravo') i.set_level(self.u1, 'bravo') self.assertTrue(i.has_level(self.u1, 'alfa')) self.assertTrue(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) def test_level_set_twice_different(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) i.set_level(self.u1, 'charlie') i.set_level(self.u1, 'bravo') self.assertTrue(i.has_level(self.u1, 'alfa')) self.assertTrue(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) def test_superuser(self): i = TestModel.objects.create(normal_field='Hello') for u, v in [(self.u1, False), (self.u2, False), (self.us, True)]: self.assertEqual(i.has_level(u, 'alfa'), v) self.assertEqual(i.has_level(u, 'bravo'), v) self.assertEqual(i.has_level(u, 'charlie'), v) def test_check_group_membership(self): groups = self.u1.groups.values_list('id', flat=True) self.assertIn(self.g1.id, groups) self.assertTrue(self.g1.user_set.filter(id=self.u2.id).exists()) def test_lowest_group_level(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) i.set_level(self.g1, 'alfa') self.assertTrue(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) def test_middle_group_level(self): i = TestModel.objects.create(normal_field='Hello') self.assertFalse(i.has_level(self.u1, 'alfa')) self.assertFalse(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) i.set_level(self.g1, 'bravo') self.assertTrue(i.has_level(self.u1, 'alfa')) self.assertTrue(i.has_level(self.u1, 'bravo')) self.assertFalse(i.has_level(self.u1, 'charlie')) def test_set_level_error_handling(self): with self.assertRaises(AttributeError): TestModel.objects.create().set_level('wrong arg', 'level') def test_get_users_with_level(self): i1 = TestModel.objects.create(normal_field='Hello') i2 = Test2Model.objects.create(normal2_field='Hello2') i1.set_level(self.u1, 'bravo') i1.set_level(self.u2, 'charlie') i2.set_level(self.u1, 'one') i2.set_level(self.us, u'three') res1 = i1.get_users_with_level() self.assertEqual([(self.u1, u'bravo'), (self.u2, u'charlie')], res1) res2 = i2.get_users_with_level() self.assertEqual([(self.u1, u'one'), (self.us, u'three')], res2) def test_get_groups_with_level(self): i1 = TestModel.objects.create(normal_field='Hello') i2 = Test2Model.objects.create(normal2_field='Hello2') i1.set_level(self.g1, 'bravo') i1.set_level(self.u2, 'charlie') i2.set_level(self.g1, 'one') i2.set_level(self.us, u'three') res1 = i1.get_groups_with_level() self.assertEqual([(self.g1, u'bravo')], res1) res2 = i2.get_groups_with_level() self.assertEqual([(self.g1, u'one')], res2) def test_object_level_unicode(self): i1 = TestModel.objects.create(normal_field='Hello') i1.set_level(self.g1, 'bravo') unicode(ObjectLevel.objects.all()[0]) views.py 0000664 0000000 0000000 00000000032 12240152740 0031612 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/acl # Create your views here. circle/ 0000775 0000000 0000000 00000000000 12240152740 0030612 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle __init__.py 0000664 0000000 0000000 00000000000 12240152740 0032711 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle settings/ 0000775 0000000 0000000 00000000000 12240152740 0032452 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle __init__.py 0000664 0000000 0000000 00000000001 12240152740 0034552 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle/settings base.py 0000664 0000000 0000000 00000023040 12240152740 0033735 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle/settings """Common settings and globals.""" from datetime import timedelta from os import environ from os.path import abspath, basename, dirname, join, normpath from json import loads # from socket import SOCK_STREAM from sys import path # Normally you should not import ANYTHING from Django directly # into your settings, but ImproperlyConfigured is an exception. from django.core.exceptions import ImproperlyConfigured def get_env_variable(var_name, default=None): """ Get the environment variable or return exception/default """ try: return environ[var_name] except KeyError: if default is None: error_msg = "Set the %s environment variable" % var_name raise ImproperlyConfigured(error_msg) else: return default ########## PATH CONFIGURATION # Absolute filesystem path to the Django project directory: DJANGO_ROOT = dirname(dirname(abspath(__file__))) # Absolute filesystem path to the top-level project folder: SITE_ROOT = dirname(DJANGO_ROOT) # Site name: SITE_NAME = basename(DJANGO_ROOT) # Add our project to our pythonpath, this way we don't need to type our project # name in our dotted import paths: path.append(DJANGO_ROOT) ########## END PATH CONFIGURATION ########## DEBUG CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = False # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug TEMPLATE_DEBUG = DEBUG ########## END DEBUG CONFIGURATION ########## MANAGER CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins ADMINS = ( ('Root', 'root@localhost'), ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS ########## END MANAGER CONFIGURATION ########## DATABASE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.' + get_env_variable('DJANG_DB_TYPE', 'postgresql_psycopg2'), 'NAME': get_env_variable('DJANGO_DB_NAME', 'circle'), 'USER': get_env_variable('DJANGO_DB_USER', 'circle'), 'PASSWORD': get_env_variable('DJANGO_DB_PASSWORD'), 'HOST': get_env_variable('DJANGO_DB_HOST', ''), 'PORT': get_env_variable('DJANGO_DB_PORT', ''), } } ########## END DATABASE CONFIGURATION ########## GENERAL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone try: with open("/etc/timezone", "r") as f: systz = f.readline().rstrip() except: systz = None TIME_ZONE = get_env_variable('DJANGO_TIME_ZONE', default=systz) # See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code LANGUAGE_CODE = 'en-us' # See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n USE_L10N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True ########## END GENERAL CONFIGURATION ########## MEDIA CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root MEDIA_ROOT = normpath(join(SITE_ROOT, 'media')) # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = get_env_variable('DJANGO_MEDIA_URL', default='/media/') ########## END MEDIA CONFIGURATION ########## STATIC FILE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = normpath(join(SITE_ROOT, 'static_collected')) # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = get_env_variable('DJANGO_STATIC_URL', default='/static/') # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = ( normpath(join(SITE_ROOT, 'static')), ) # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) ########## END STATIC FILE CONFIGURATION ########## SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key # Note: This key should only be used for development and testing. SECRET_KEY = r"a5w*b0wajigd^kd7b=@w=5=+l_0c62@vljnhzqu3dfc@vx2jw-" ########## END SECRET CONFIGURATION ########## SITE CONFIGURATION # Hosts/domain names that are valid for this site # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts ALLOWED_HOSTS = [] ########## END SITE CONFIGURATION ########## FIXTURE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS FIXTURE_DIRS = ( normpath(join(SITE_ROOT, 'fixtures')), ) ########## END FIXTURE CONFIGURATION ########## TEMPLATE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_DIRS = ( normpath(join(SITE_ROOT, 'templates')), ) ########## END TEMPLATE CONFIGURATION ########## MIDDLEWARE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes MIDDLEWARE_CLASSES = ( # Default Django middleware. 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) ########## END MIDDLEWARE CONFIGURATION ########## URL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf ROOT_URLCONF = '%s.urls' % SITE_NAME ########## END URL CONFIGURATION ########## APP CONFIGURATION DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Useful template tags: # 'django.contrib.humanize', # Admin panel and documentation: 'django.contrib.admin', # 'django.contrib.admindocs', ) THIRD_PARTY_APPS = ( 'south', 'django_tables2', 'crispy_forms', 'djcelery', 'sizefield', 'taggit', ) # Apps specific for this project go here. LOCAL_APPS = ( 'common', 'vm', 'storage', 'firewall', 'network', 'dashboard', 'manager', 'acl', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS ########## END APP CONFIGURATION ########## LOGGING CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': '%(asctime)s [%(levelname)s]: %(name)s %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S', }, }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' }, 'syslog': { 'level': 'INFO', 'class': 'logging.handlers.SysLogHandler', 'formatter': 'simple', 'address': '/dev/log', # 'socktype': SOCK_STREAM, # 'address': ('host', '514'), } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins', 'syslog'], 'level': 'INFO', 'propagate': True, }, } } ########## END LOGGING CONFIGURATION ########## WSGI CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME ########## END WSGI CONFIGURATION FIREWALL_SETTINGS = loads(get_env_variable('DJANGO_FIREWALL_SETTINGS')) CRISPY_TEMPLATE_PACK = 'bootstrap3' # format: id: (name, port, protocol) VM_ACCESS_PROTOCOLS = loads(get_env_variable('DJANGO_VM_ACCESS_PROTOCOLS', '''{"nx": ["NX", 22, "tcp"], "rdp": ["RDP", 3389, "tcp"], "ssh": ["SSH", 22, "tcp"]}''')) VM_SCHEDULER = 'manager.scheduler' BROKER_URL = get_env_variable('AMQP_URI') # Set up periodic firewall tasks CELERYBEAT_SCHEDULE = { 'blabla': { 'task': 'firewall.tasks.local_tasks.periodic_task', 'schedule': timedelta(seconds=5), }, } local.py 0000664 0000000 0000000 00000004322 12240152740 0034117 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle/settings """Development settings and globals.""" # from os.path import join, normpath from base import * ########## DEBUG CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug TEMPLATE_DEBUG = DEBUG ########## END DEBUG CONFIGURATION ########## EMAIL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' ########## END EMAIL CONFIGURATION ########## DATABASE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': normpath(join(DJANGO_ROOT, 'default.db')), # 'USER': '', # 'PASSWORD': '', # 'HOST': '', # 'PORT': '', # } # } ########## END DATABASE CONFIGURATION ########## CACHE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#caches CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } } ########## END CACHE CONFIGURATION ########## TOOLBAR CONFIGURATION # https://github.com/django-debug-toolbar/django-debug-toolbar#installation if get_env_variable('DJANGO_TOOLBAR', 'FALSE') == 'TRUE': INSTALLED_APPS += ( 'debug_toolbar', ) # https://github.com/django-debug-toolbar/django-debug-toolbar#installation INTERNAL_IPS = ( get_env_variable('SSH_CLIENT', '127.0.0.1').split(' ')[0], ) # https://github.com/django-debug-toolbar/django-debug-toolbar#installation MIDDLEWARE_CLASSES += ( 'debug_toolbar.middleware.DebugToolbarMiddleware', ) # https://github.com/django-debug-toolbar/django-debug-toolbar#installation DEBUG_TOOLBAR_CONFIG = { 'INTERCEPT_REDIRECTS': False, 'SHOW_TEMPLATE_CONTEXT': True, } ########## END TOOLBAR CONFIGURATION LOGGING['handlers']['console'] = {'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple'} for i in LOCAL_APPS: LOGGING['loggers'][i] = {'handlers': ['console'], 'level': 'DEBUG'} production.py 0000664 0000000 0000000 00000004533 12240152740 0035217 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle/settings """Production settings and globals.""" from os import environ from base import * def get_env_setting(setting): """ Get the environment setting or return exception """ try: return environ[setting] except KeyError: error_msg = "Set the %s env variable" % setting raise ImproperlyConfigured(error_msg) ########## HOST CONFIGURATION # See: https://docs.djangoproject.com/en/1.5/releases/1.5/#allowed-hosts-required-in-production ALLOWED_HOSTS = get_env_setting('DJANGO_ALLOWED_HOSTS').split(',') ########## END HOST CONFIGURATION ########## EMAIL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' try: # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-host EMAIL_HOST = environ.get('EMAIL_HOST') except ImproperlyConfigured: pass else: # https://docs.djangoproject.com/en/dev/ref/settings/#email-host-password EMAIL_HOST_PASSWORD = environ.get('EMAIL_HOST_PASSWORD', '') # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-host-user EMAIL_HOST_USER = environ.get('EMAIL_HOST_USER', 'your_email@example.com') # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-port EMAIL_PORT = environ.get('EMAIL_PORT', 587) # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-use-tls EMAIL_USE_TLS = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix EMAIL_SUBJECT_PREFIX = '[%s] ' % SITE_NAME # See: https://docs.djangoproject.com/en/dev/ref/settings/#server-email SERVER_EMAIL = EMAIL_HOST_USER ########## END EMAIL CONFIGURATION ########## CACHE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#caches try: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': get_env_variable('DJANGO_MEMCACHED'), } } except ImproperlyConfigured: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': SITE_NAME, } } ########## END CACHE CONFIGURATION ########## SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key SECRET_KEY = get_env_setting('SECRET_KEY') ########## END SECRET CONFIGURATION test.py 0000664 0000000 0000000 00000000763 12240152740 0034011 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle/settings from base import * ########## TEST SETTINGS TEST_RUNNER = 'discover_runner.DiscoverRunner' TEST_DISCOVER_TOP_LEVEL = SITE_ROOT TEST_DISCOVER_ROOT = SITE_ROOT TEST_DISCOVER_PATTERN = "test_*.py" ########## IN-MEMORY TEST DATABASE DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", "USER": "", "PASSWORD": "", "HOST": "", "PORT": "", }, } SOUTH_TESTS_MIGRATE = False INSTALLED_APPS += ( 'acl.tests', ) urls.py 0000664 0000000 0000000 00000001175 12240152740 0032155 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle from django.conf.urls import patterns, include, url # from django.views.generic import TemplateView from django.contrib import admin admin.autodiscover() urlpatterns = patterns( '', #url(r'^$', TemplateView.as_view(template_name='base.html')), # Examples: # url(r'^$', 'circle.views.home', name='home'), # url(r'^circle/', include('circle.foo.urls')), # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^network/', include('network.urls')), url(r'^dashboard/', include('dashboard.urls')), url(r'^vm-api/', include('vm.urls')), ) wsgi.py 0000664 0000000 0000000 00000003421 12240152740 0032135 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/circle """ WSGI config for circle project. This module contains the WSGI application used by Django's development server and any production WSGI deployments. It should expose a module-level variable named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover this application via the ``WSGI_APPLICATION`` setting. Usually you will have the standard Django WSGI application here, but it also might make sense to replace the whole Django WSGI application with a custom one that later delegates to the Django one. For example, you could introduce WSGI middleware here, or combine a Django application with an application of another framework. """ import os from os.path import abspath, dirname from sys import path SITE_ROOT = dirname(dirname(abspath(__file__))) path.append(SITE_ROOT) # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # if running multiple sites in the same mod_wsgi process. To fix this, use # mod_wsgi daemon mode with each site in its own daemon process, or use # os.environ["DJANGO_SETTINGS_MODULE"] = "jajaja.settings" os.environ.setdefault("DJANGO_SETTINGS_MODULE", "circle.settings.production") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION # setting points here. from django.core.wsgi import get_wsgi_application _application = get_wsgi_application() def application(environ, start_response): # copy DJANGO_* wsgi-env vars to process-env for i in environ.keys(): if i.startswith('DJANGO_'): os.environ[i] = environ[i] return _application(environ, start_response) # Apply WSGI middleware here. # from helloworld.wsgi import HelloWorldApplication # application = HelloWorldApplication(application) common/ 0000775 0000000 0000000 00000000000 12240152740 0030641 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle __init__.py 0000664 0000000 0000000 00000000000 12240152740 0032740 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/common models.py 0000664 0000000 0000000 00000003474 12240152740 0032506 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/common from django.contrib.auth.models import User from django.db.models import (CharField, DateTimeField, ForeignKey, TextField) from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from model_utils.models import TimeStampedModel def activitycontextimpl(act): try: yield act except Exception as e: act.finish(str(e)) raise e else: act.finish() class ActivityModel(TimeStampedModel): activity_code = CharField(max_length=100, verbose_name=_('activity code')) parent = ForeignKey('self', blank=True, null=True) task_uuid = CharField(blank=True, max_length=50, null=True, unique=True, help_text=_('Celery task unique identifier.'), verbose_name=_('task_uuid')) user = ForeignKey(User, blank=True, null=True, verbose_name=_('user'), help_text=_('The person who started this activity.')) started = DateTimeField(verbose_name=_('started at'), blank=True, null=True, help_text=_('Time of activity initiation.')) finished = DateTimeField(verbose_name=_('finished at'), blank=True, null=True, help_text=_('Time of activity finalization.')) result = TextField(verbose_name=_('result'), blank=True, null=True, help_text=_('Human readable result of activity.')) def __unicode__(self): if self.parent: return self.parent.activity_code + "->" + self.activity_code else: return self.activity_code class Meta: abstract = True def finish(self, result=None): if not self.finished: self.finished = timezone.now() self.result = result self.save() dashboard/ 0000775 0000000 0000000 00000000000 12240152740 0031300 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle __init__.py 0000664 0000000 0000000 00000000000 12240152740 0033377 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard fixtures/ 0000775 0000000 0000000 00000000000 12240152740 0033151 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard test-vm-fixture.json 0000664 0000000 0000000 00000061756 12240152740 0037146 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/fixtures [ { "pk": 1, "model": "sites.site", "fields": { "domain": "example.com", "name": "example.com" } }, { "pk": 1, "model": "vm.lease", "fields": { "suspend_interval_seconds": 18000, "name": "lab", "delete_interval_seconds": 180000 } }, { "pk": 1, "model": "storage.datastore", "fields": { "path": "/disks", "hostname": "wut", "name": "diszkek" } }, { "pk": 1, "model": "storage.disk", "fields": { "name": "diszk", "created": "2013-09-16T09:05:56.926Z", "modified": "2013-09-19T09:10:25.117Z", "filename": "disc.img", "destroyed": null, "base": null, "ready": true, "datastore": 1, "dev_num": "a", "type": "raw-rw", "size": 8589934592 } }, { "pk": 1, "model": "acl.level", "fields": { "codename": "owner", "weight": 2, "name": "owner", "content_type": 15 } }, { "pk": 2, "model": "acl.level", "fields": { "codename": "operator", "weight": 1, "name": "operator", "content_type": 15 } }, { "pk": 3, "model": "acl.level", "fields": { "codename": "user", "weight": 0, "name": "user", "content_type": 15 } }, { "pk": 1, "model": "auth.permission", "fields": { "codename": "add_permission", "name": "Can add permission", "content_type": 1 } }, { "pk": 2, "model": "auth.permission", "fields": { "codename": "change_permission", "name": "Can change permission", "content_type": 1 } }, { "pk": 3, "model": "auth.permission", "fields": { "codename": "delete_permission", "name": "Can delete permission", "content_type": 1 } }, { "pk": 4, "model": "auth.permission", "fields": { "codename": "add_group", "name": "Can add group", "content_type": 2 } }, { "pk": 5, "model": "auth.permission", "fields": { "codename": "change_group", "name": "Can change group", "content_type": 2 } }, { "pk": 6, "model": "auth.permission", "fields": { "codename": "delete_group", "name": "Can delete group", "content_type": 2 } }, { "pk": 7, "model": "auth.permission", "fields": { "codename": "add_user", "name": "Can add user", "content_type": 3 } }, { "pk": 8, "model": "auth.permission", "fields": { "codename": "change_user", "name": "Can change user", "content_type": 3 } }, { "pk": 9, "model": "auth.permission", "fields": { "codename": "delete_user", "name": "Can delete user", "content_type": 3 } }, { "pk": 10, "model": "auth.permission", "fields": { "codename": "add_contenttype", "name": "Can add content type", "content_type": 4 } }, { "pk": 11, "model": "auth.permission", "fields": { "codename": "change_contenttype", "name": "Can change content type", "content_type": 4 } }, { "pk": 12, "model": "auth.permission", "fields": { "codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4 } }, { "pk": 13, "model": "auth.permission", "fields": { "codename": "add_session", "name": "Can add session", "content_type": 5 } }, { "pk": 14, "model": "auth.permission", "fields": { "codename": "change_session", "name": "Can change session", "content_type": 5 } }, { "pk": 15, "model": "auth.permission", "fields": { "codename": "delete_session", "name": "Can delete session", "content_type": 5 } }, { "pk": 16, "model": "auth.permission", "fields": { "codename": "add_site", "name": "Can add site", "content_type": 6 } }, { "pk": 17, "model": "auth.permission", "fields": { "codename": "change_site", "name": "Can change site", "content_type": 6 } }, { "pk": 18, "model": "auth.permission", "fields": { "codename": "delete_site", "name": "Can delete site", "content_type": 6 } }, { "pk": 19, "model": "auth.permission", "fields": { "codename": "add_logentry", "name": "Can add log entry", "content_type": 7 } }, { "pk": 20, "model": "auth.permission", "fields": { "codename": "change_logentry", "name": "Can change log entry", "content_type": 7 } }, { "pk": 21, "model": "auth.permission", "fields": { "codename": "delete_logentry", "name": "Can delete log entry", "content_type": 7 } }, { "pk": 22, "model": "auth.permission", "fields": { "codename": "add_migrationhistory", "name": "Can add migration history", "content_type": 8 } }, { "pk": 23, "model": "auth.permission", "fields": { "codename": "change_migrationhistory", "name": "Can change migration history", "content_type": 8 } }, { "pk": 24, "model": "auth.permission", "fields": { "codename": "delete_migrationhistory", "name": "Can delete migration history", "content_type": 8 } }, { "pk": 25, "model": "auth.permission", "fields": { "codename": "add_namedbaseresourceconfig", "name": "Can add named base resource config", "content_type": 9 } }, { "pk": 26, "model": "auth.permission", "fields": { "codename": "change_namedbaseresourceconfig", "name": "Can change named base resource config", "content_type": 9 } }, { "pk": 27, "model": "auth.permission", "fields": { "codename": "delete_namedbaseresourceconfig", "name": "Can delete named base resource config", "content_type": 9 } }, { "pk": 28, "model": "auth.permission", "fields": { "codename": "add_node", "name": "Can add node", "content_type": 10 } }, { "pk": 29, "model": "auth.permission", "fields": { "codename": "change_node", "name": "Can change node", "content_type": 10 } }, { "pk": 30, "model": "auth.permission", "fields": { "codename": "delete_node", "name": "Can delete node", "content_type": 10 } }, { "pk": 31, "model": "auth.permission", "fields": { "codename": "add_nodeactivity", "name": "Can add node activity", "content_type": 11 } }, { "pk": 32, "model": "auth.permission", "fields": { "codename": "change_nodeactivity", "name": "Can change node activity", "content_type": 11 } }, { "pk": 33, "model": "auth.permission", "fields": { "codename": "delete_nodeactivity", "name": "Can delete node activity", "content_type": 11 } }, { "pk": 34, "model": "auth.permission", "fields": { "codename": "add_lease", "name": "Can add lease", "content_type": 12 } }, { "pk": 35, "model": "auth.permission", "fields": { "codename": "change_lease", "name": "Can change lease", "content_type": 12 } }, { "pk": 36, "model": "auth.permission", "fields": { "codename": "delete_lease", "name": "Can delete lease", "content_type": 12 } }, { "pk": 37, "model": "auth.permission", "fields": { "codename": "add_instancetemplate", "name": "Can add template", "content_type": 13 } }, { "pk": 38, "model": "auth.permission", "fields": { "codename": "change_instancetemplate", "name": "Can change template", "content_type": 13 } }, { "pk": 39, "model": "auth.permission", "fields": { "codename": "delete_instancetemplate", "name": "Can delete template", "content_type": 13 } }, { "pk": 40, "model": "auth.permission", "fields": { "codename": "add_interfacetemplate", "name": "Can add interface template", "content_type": 14 } }, { "pk": 41, "model": "auth.permission", "fields": { "codename": "change_interfacetemplate", "name": "Can change interface template", "content_type": 14 } }, { "pk": 42, "model": "auth.permission", "fields": { "codename": "delete_interfacetemplate", "name": "Can delete interface template", "content_type": 14 } }, { "pk": 43, "model": "auth.permission", "fields": { "codename": "add_instance", "name": "Can add instance", "content_type": 15 } }, { "pk": 44, "model": "auth.permission", "fields": { "codename": "change_instance", "name": "Can change instance", "content_type": 15 } }, { "pk": 45, "model": "auth.permission", "fields": { "codename": "delete_instance", "name": "Can delete instance", "content_type": 15 } }, { "pk": 46, "model": "auth.permission", "fields": { "codename": "add_instanceactivity", "name": "Can add instance activity", "content_type": 16 } }, { "pk": 47, "model": "auth.permission", "fields": { "codename": "change_instanceactivity", "name": "Can change instance activity", "content_type": 16 } }, { "pk": 48, "model": "auth.permission", "fields": { "codename": "delete_instanceactivity", "name": "Can delete instance activity", "content_type": 16 } }, { "pk": 49, "model": "auth.permission", "fields": { "codename": "add_interface", "name": "Can add interface", "content_type": 17 } }, { "pk": 50, "model": "auth.permission", "fields": { "codename": "change_interface", "name": "Can change interface", "content_type": 17 } }, { "pk": 51, "model": "auth.permission", "fields": { "codename": "delete_interface", "name": "Can delete interface", "content_type": 17 } }, { "pk": 52, "model": "auth.permission", "fields": { "codename": "add_datastore", "name": "Can add datastore", "content_type": 18 } }, { "pk": 53, "model": "auth.permission", "fields": { "codename": "change_datastore", "name": "Can change datastore", "content_type": 18 } }, { "pk": 54, "model": "auth.permission", "fields": { "codename": "delete_datastore", "name": "Can delete datastore", "content_type": 18 } }, { "pk": 55, "model": "auth.permission", "fields": { "codename": "add_disk", "name": "Can add disk", "content_type": 19 } }, { "pk": 56, "model": "auth.permission", "fields": { "codename": "change_disk", "name": "Can change disk", "content_type": 19 } }, { "pk": 57, "model": "auth.permission", "fields": { "codename": "delete_disk", "name": "Can delete disk", "content_type": 19 } }, { "pk": 58, "model": "auth.permission", "fields": { "codename": "add_rule", "name": "Can add rule", "content_type": 20 } }, { "pk": 59, "model": "auth.permission", "fields": { "codename": "change_rule", "name": "Can change rule", "content_type": 20 } }, { "pk": 60, "model": "auth.permission", "fields": { "codename": "delete_rule", "name": "Can delete rule", "content_type": 20 } }, { "pk": 61, "model": "auth.permission", "fields": { "codename": "add_vlan", "name": "Can add vlan", "content_type": 21 } }, { "pk": 62, "model": "auth.permission", "fields": { "codename": "change_vlan", "name": "Can change vlan", "content_type": 21 } }, { "pk": 63, "model": "auth.permission", "fields": { "codename": "delete_vlan", "name": "Can delete vlan", "content_type": 21 } }, { "pk": 64, "model": "auth.permission", "fields": { "codename": "add_vlangroup", "name": "Can add vlan group", "content_type": 22 } }, { "pk": 65, "model": "auth.permission", "fields": { "codename": "change_vlangroup", "name": "Can change vlan group", "content_type": 22 } }, { "pk": 66, "model": "auth.permission", "fields": { "codename": "delete_vlangroup", "name": "Can delete vlan group", "content_type": 22 } }, { "pk": 67, "model": "auth.permission", "fields": { "codename": "add_group", "name": "Can add group", "content_type": 23 } }, { "pk": 68, "model": "auth.permission", "fields": { "codename": "change_group", "name": "Can change group", "content_type": 23 } }, { "pk": 69, "model": "auth.permission", "fields": { "codename": "delete_group", "name": "Can delete group", "content_type": 23 } }, { "pk": 70, "model": "auth.permission", "fields": { "codename": "add_host", "name": "Can add host", "content_type": 24 } }, { "pk": 71, "model": "auth.permission", "fields": { "codename": "change_host", "name": "Can change host", "content_type": 24 } }, { "pk": 72, "model": "auth.permission", "fields": { "codename": "delete_host", "name": "Can delete host", "content_type": 24 } }, { "pk": 73, "model": "auth.permission", "fields": { "codename": "add_firewall", "name": "Can add firewall", "content_type": 25 } }, { "pk": 74, "model": "auth.permission", "fields": { "codename": "change_firewall", "name": "Can change firewall", "content_type": 25 } }, { "pk": 75, "model": "auth.permission", "fields": { "codename": "delete_firewall", "name": "Can delete firewall", "content_type": 25 } }, { "pk": 76, "model": "auth.permission", "fields": { "codename": "add_domain", "name": "Can add domain", "content_type": 26 } }, { "pk": 77, "model": "auth.permission", "fields": { "codename": "change_domain", "name": "Can change domain", "content_type": 26 } }, { "pk": 78, "model": "auth.permission", "fields": { "codename": "delete_domain", "name": "Can delete domain", "content_type": 26 } }, { "pk": 79, "model": "auth.permission", "fields": { "codename": "add_record", "name": "Can add record", "content_type": 27 } }, { "pk": 80, "model": "auth.permission", "fields": { "codename": "change_record", "name": "Can change record", "content_type": 27 } }, { "pk": 81, "model": "auth.permission", "fields": { "codename": "delete_record", "name": "Can delete record", "content_type": 27 } }, { "pk": 82, "model": "auth.permission", "fields": { "codename": "add_blacklist", "name": "Can add blacklist", "content_type": 28 } }, { "pk": 83, "model": "auth.permission", "fields": { "codename": "change_blacklist", "name": "Can change blacklist", "content_type": 28 } }, { "pk": 84, "model": "auth.permission", "fields": { "codename": "delete_blacklist", "name": "Can delete blacklist", "content_type": 28 } }, { "pk": 85, "model": "auth.permission", "fields": { "codename": "add_taskmeta", "name": "Can add task state", "content_type": 29 } }, { "pk": 86, "model": "auth.permission", "fields": { "codename": "change_taskmeta", "name": "Can change task state", "content_type": 29 } }, { "pk": 87, "model": "auth.permission", "fields": { "codename": "delete_taskmeta", "name": "Can delete task state", "content_type": 29 } }, { "pk": 88, "model": "auth.permission", "fields": { "codename": "add_tasksetmeta", "name": "Can add saved group result", "content_type": 30 } }, { "pk": 89, "model": "auth.permission", "fields": { "codename": "change_tasksetmeta", "name": "Can change saved group result", "content_type": 30 } }, { "pk": 90, "model": "auth.permission", "fields": { "codename": "delete_tasksetmeta", "name": "Can delete saved group result", "content_type": 30 } }, { "pk": 91, "model": "auth.permission", "fields": { "codename": "add_intervalschedule", "name": "Can add interval", "content_type": 31 } }, { "pk": 92, "model": "auth.permission", "fields": { "codename": "change_intervalschedule", "name": "Can change interval", "content_type": 31 } }, { "pk": 93, "model": "auth.permission", "fields": { "codename": "delete_intervalschedule", "name": "Can delete interval", "content_type": 31 } }, { "pk": 94, "model": "auth.permission", "fields": { "codename": "add_crontabschedule", "name": "Can add crontab", "content_type": 32 } }, { "pk": 95, "model": "auth.permission", "fields": { "codename": "change_crontabschedule", "name": "Can change crontab", "content_type": 32 } }, { "pk": 96, "model": "auth.permission", "fields": { "codename": "delete_crontabschedule", "name": "Can delete crontab", "content_type": 32 } }, { "pk": 97, "model": "auth.permission", "fields": { "codename": "add_periodictasks", "name": "Can add periodic tasks", "content_type": 33 } }, { "pk": 98, "model": "auth.permission", "fields": { "codename": "change_periodictasks", "name": "Can change periodic tasks", "content_type": 33 } }, { "pk": 99, "model": "auth.permission", "fields": { "codename": "delete_periodictasks", "name": "Can delete periodic tasks", "content_type": 33 } }, { "pk": 100, "model": "auth.permission", "fields": { "codename": "add_periodictask", "name": "Can add periodic task", "content_type": 34 } }, { "pk": 101, "model": "auth.permission", "fields": { "codename": "change_periodictask", "name": "Can change periodic task", "content_type": 34 } }, { "pk": 102, "model": "auth.permission", "fields": { "codename": "delete_periodictask", "name": "Can delete periodic task", "content_type": 34 } }, { "pk": 103, "model": "auth.permission", "fields": { "codename": "add_workerstate", "name": "Can add worker", "content_type": 35 } }, { "pk": 104, "model": "auth.permission", "fields": { "codename": "change_workerstate", "name": "Can change worker", "content_type": 35 } }, { "pk": 105, "model": "auth.permission", "fields": { "codename": "delete_workerstate", "name": "Can delete worker", "content_type": 35 } }, { "pk": 106, "model": "auth.permission", "fields": { "codename": "add_taskstate", "name": "Can add task", "content_type": 36 } }, { "pk": 107, "model": "auth.permission", "fields": { "codename": "change_taskstate", "name": "Can change task", "content_type": 36 } }, { "pk": 108, "model": "auth.permission", "fields": { "codename": "delete_taskstate", "name": "Can delete task", "content_type": 36 } }, { "pk": 109, "model": "auth.permission", "fields": { "codename": "add_userobjectpermission", "name": "Can add user object permission", "content_type": 37 } }, { "pk": 110, "model": "auth.permission", "fields": { "codename": "change_userobjectpermission", "name": "Can change user object permission", "content_type": 37 } }, { "pk": 111, "model": "auth.permission", "fields": { "codename": "delete_userobjectpermission", "name": "Can delete user object permission", "content_type": 37 } }, { "pk": 112, "model": "auth.permission", "fields": { "codename": "add_groupobjectpermission", "name": "Can add group object permission", "content_type": 38 } }, { "pk": 113, "model": "auth.permission", "fields": { "codename": "change_groupobjectpermission", "name": "Can change group object permission", "content_type": 38 } }, { "pk": 114, "model": "auth.permission", "fields": { "codename": "delete_groupobjectpermission", "name": "Can delete group object permission", "content_type": 38 } }, { "pk": 115, "model": "auth.permission", "fields": { "codename": "own_instance", "name": "owner", "content_type": 15 } }, { "pk": 116, "model": "auth.permission", "fields": { "codename": "operate_instance", "name": "operator", "content_type": 15 } }, { "pk": 117, "model": "auth.permission", "fields": { "codename": "use_instance", "name": "user", "content_type": 15 } }, { "pk": 118, "model": "auth.permission", "fields": { "codename": "add_diskactivity", "name": "Can add disk activity", "content_type": 39 } }, { "pk": 119, "model": "auth.permission", "fields": { "codename": "change_diskactivity", "name": "Can change disk activity", "content_type": 39 } }, { "pk": 120, "model": "auth.permission", "fields": { "codename": "delete_diskactivity", "name": "Can delete disk activity", "content_type": 39 } }, { "pk": 121, "model": "auth.permission", "fields": { "codename": "add_level", "name": "Can add level", "content_type": 40 } }, { "pk": 122, "model": "auth.permission", "fields": { "codename": "change_level", "name": "Can change level", "content_type": 40 } }, { "pk": 123, "model": "auth.permission", "fields": { "codename": "delete_level", "name": "Can delete level", "content_type": 40 } }, { "pk": 127, "model": "auth.permission", "fields": { "codename": "add_objectlevel", "name": "Can add object level", "content_type": 42 } }, { "pk": 128, "model": "auth.permission", "fields": { "codename": "change_objectlevel", "name": "Can change object level", "content_type": 42 } }, { "pk": 129, "model": "auth.permission", "fields": { "codename": "delete_objectlevel", "name": "Can delete object level", "content_type": 42 } }, { "pk": 130, "model": "auth.permission", "fields": { "codename": "add_switchport", "name": "Can add switch port", "content_type": 43 } }, { "pk": 131, "model": "auth.permission", "fields": { "codename": "change_switchport", "name": "Can change switch port", "content_type": 43 } }, { "pk": 132, "model": "auth.permission", "fields": { "codename": "delete_switchport", "name": "Can delete switch port", "content_type": 43 } }, { "pk": 133, "model": "auth.permission", "fields": { "codename": "add_ethernetdevice", "name": "Can add ethernet device", "content_type": 44 } }, { "pk": 134, "model": "auth.permission", "fields": { "codename": "change_ethernetdevice", "name": "Can change ethernet device", "content_type": 44 } }, { "pk": 135, "model": "auth.permission", "fields": { "codename": "delete_ethernetdevice", "name": "Can delete ethernet device", "content_type": 44 } }, { "pk": 1, "model": "auth.group", "fields": { "name": "csopi", "permissions": [] } }, { "pk": 2, "model": "auth.group", "fields": { "name": "akkorszia", "permissions": [] } }, { "pk": 3, "model": "auth.group", "fields": { "name": "akkountsoherek", "permissions": [] } }, { "pk": 4, "model": "auth.group", "fields": { "name": "helog", "permissions": [] } }, { "pk": -1, "model": "auth.user", "fields": { "username": "AnonymousUser", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2013-09-30T12:37:38.484Z", "groups": [], "user_permissions": [], "password": "", "email": "", "date_joined": "2013-09-30T12:37:38.484Z" } }, { "pk": 1, "model": "auth.user", "fields": { "username": "test", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2013-11-09T03:40:23.157Z", "groups": [], "user_permissions": [ 115 ], "password": "pbkdf2_sha256$10000$KIoeMs78MiOj$PnVXn3YJMehbOciBO32CMzqL0ZnQrzrdb7+b5dE13os=", "email": "test@example.org", "date_joined": "2013-09-04T15:29:49.914Z" } }, { "pk": 3, "model": "auth.user", "fields": { "username": "proba", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2013-10-14T06:59:48Z", "groups": [ 1 ], "user_permissions": [], "password": "", "email": "", "date_joined": "2013-10-14T06:59:48Z" } }, { "pk": 4, "model": "auth.user", "fields": { "username": "helo", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2013-11-09T01:11:41.534Z", "groups": [ 4 ], "user_permissions": [], "password": "", "email": "", "date_joined": "2013-11-09T01:11:41.534Z" } }, { "pk": 1, "model": "vm.instance", "fields": { "destoryed": null, "disks": [ 1 ], "boot_menu": false, "owner": 1, "time_of_delete": null, "max_ram_size": 200, "pw": "ads", "time_of_suspend": null, "ram_size": 200, "priority": 4, "active_since": null, "state": "NOSTATE", "template": null, "access_method": "nx", "lease": 1, "node": null, "description": "", "arch": "x86_64", "name": "vanneve", "created": "2013-09-16T09:05:59.991Z", "raw_data": "", "vnc_port": 1234, "num_cores": 2, "modified": "2013-10-14T07:27:38.192Z" } } ] models.py 0000664 0000000 0000000 00000000071 12240152740 0033133 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard from django.db import models # Create your models here. static/ 0000775 0000000 0000000 00000000000 12240152740 0032567 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard dashboard/ 0000775 0000000 0000000 00000000000 12240152740 0034516 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static bootstrap-slider/ 0000775 0000000 0000000 00000000000 12240152740 0040013 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard bootstrap-slider.js 0000664 0000000 0000000 00000025756 12240152740 0043665 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard/bootstrap-slider /* ========================================================= * bootstrap-slider.js v2.0.0 * http://www.eyecon.ro/bootstrap-slider * ========================================================= * Copyright 2012 Stefan Petre * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ========================================================= */ !function( $ ) { var Slider = function(element, options) { this.element = $(element); this.picker = $('
') .insertBefore(this.element) .append(this.element); this.id = this.element.data('slider-id')||options.id; if (this.id) { this.picker[0].id = this.id; } if (typeof Modernizr !== 'undefined' && Modernizr.touch) { this.touchCapable = true; } var tooltip = this.element.data('slider-tooltip')||options.tooltip; this.tooltip = this.picker.find('.tooltip'); this.tooltipInner = this.tooltip.find('div.tooltip-inner'); this.orientation = this.element.data('slider-orientation')||options.orientation; switch(this.orientation) { case 'vertical': this.picker.addClass('slider-vertical'); this.stylePos = 'top'; this.mousePos = 'pageY'; this.sizePos = 'offsetHeight'; this.tooltip.addClass('right')[0].style.left = '100%'; break; default: this.picker .addClass('slider-horizontal') .css('width', this.element.outerWidth()); this.orientation = 'horizontal'; this.stylePos = 'left'; this.mousePos = 'pageX'; this.sizePos = 'offsetWidth'; this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px'; break; } this.min = this.element.data('slider-min')||options.min; this.max = this.element.data('slider-max')||options.max; this.step = this.element.data('slider-step')||options.step; this.value = this.element.data('slider-value')||options.value; if (this.value[1]) { this.range = true; } this.selection = this.element.data('slider-selection')||options.selection; this.selectionEl = this.picker.find('.slider-selection'); if (this.selection === 'none') { this.selectionEl.addClass('hide'); } this.selectionElStyle = this.selectionEl[0].style; this.handle1 = this.picker.find('.slider-handle:first'); this.handle1Stype = this.handle1[0].style; this.handle2 = this.picker.find('.slider-handle:last'); this.handle2Stype = this.handle2[0].style; var handle = this.element.data('slider-handle')||options.handle; switch(handle) { case 'round': this.handle1.addClass('round'); this.handle2.addClass('round'); break case 'triangle': this.handle1.addClass('triangle'); this.handle2.addClass('triangle'); break } if (this.range) { this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); } else { this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; this.handle2.addClass('hide'); if (this.selection == 'after') { this.value[1] = this.max; } else { this.value[1] = this.min; } } this.diff = this.max - this.min; this.percentage = [ (this.value[0]-this.min)*100/this.diff, (this.value[1]-this.min)*100/this.diff, this.step*100/this.diff ]; this.offset = this.picker.offset(); this.size = this.picker[0][this.sizePos]; this.formater = options.formater; this.layout(); if (this.touchCapable) { // Touch: Bind touch events: this.picker.on({ touchstart: $.proxy(this.mousedown, this) }); } else { this.picker.on({ mousedown: $.proxy(this.mousedown, this) }); } if (tooltip === 'show') { this.picker.on({ mouseenter: $.proxy(this.showTooltip, this), mouseleave: $.proxy(this.hideTooltip, this) }); } else { this.tooltip.addClass('hide'); } }; Slider.prototype = { constructor: Slider, over: false, inDrag: false, showTooltip: function(){ this.tooltip.addClass('in'); //var left = Math.round(this.percent*this.width); //this.tooltip.css('left', left - this.tooltip.outerWidth()/2); this.over = true; }, hideTooltip: function(){ if (this.inDrag === false) { this.tooltip.removeClass('in'); } this.over = false; }, layout: function(){ this.handle1Stype[this.stylePos] = this.percentage[0]+'%'; this.handle2Stype[this.stylePos] = this.percentage[1]+'%'; if (this.orientation == 'vertical') { this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%'; this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; } else { this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%'; this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; } if (this.range) { this.tooltipInner.text( this.formater(this.value[0]) + ' : ' + this.formater(this.value[1]) ); this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; } else { this.tooltipInner.text( this.formater(this.value[0]) ); this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; } }, mousedown: function(ev) { // Touch: Get the original event: if (this.touchCapable && ev.type === 'touchstart') { ev = ev.originalEvent; } this.offset = this.picker.offset(); this.size = this.picker[0][this.sizePos]; var percentage = this.getPercentage(ev); if (this.range) { var diff1 = Math.abs(this.percentage[0] - percentage); var diff2 = Math.abs(this.percentage[1] - percentage); this.dragged = (diff1 < diff2) ? 0 : 1; } else { this.dragged = 0; } this.percentage[this.dragged] = percentage; this.layout(); if (this.touchCapable) { // Touch: Bind touch events: $(document).on({ touchmove: $.proxy(this.mousemove, this), touchend: $.proxy(this.mouseup, this) }); } else { $(document).on({ mousemove: $.proxy(this.mousemove, this), mouseup: $.proxy(this.mouseup, this) }); } this.inDrag = true; var val = this.calculateValue(); this.element.trigger({ type: 'slideStart', value: val }).trigger({ type: 'slide', value: val }); return false; }, mousemove: function(ev) { // Touch: Get the original event: if (this.touchCapable && ev.type === 'touchmove') { ev = ev.originalEvent; } var percentage = this.getPercentage(ev); if (this.range) { if (this.dragged === 0 && this.percentage[1] < percentage) { this.percentage[0] = this.percentage[1]; this.dragged = 1; } else if (this.dragged === 1 && this.percentage[0] > percentage) { this.percentage[1] = this.percentage[0]; this.dragged = 0; } } this.percentage[this.dragged] = percentage; this.layout(); var val = this.calculateValue(); this.element .trigger({ type: 'slide', value: val }) .data('value', val) .prop('value', val); return false; }, mouseup: function(ev) { if (this.touchCapable) { // Touch: Bind touch events: $(document).off({ touchmove: this.mousemove, touchend: this.mouseup }); } else { $(document).off({ mousemove: this.mousemove, mouseup: this.mouseup }); } this.inDrag = false; if (this.over == false) { this.hideTooltip(); } this.element; var val = this.calculateValue(); this.element .trigger({ type: 'slideStop', value: val }) .data('value', val) .prop('value', val); return false; }, calculateValue: function() { var val; if (this.range) { val = [ (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step), (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step) ]; this.value = val; } else { val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step); this.value = [val, this.value[1]]; } return val; }, getPercentage: function(ev) { if (this.touchCapable) { ev = ev.touches[0]; } var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size; percentage = Math.round(percentage/this.percentage[2])*this.percentage[2]; return Math.max(0, Math.min(100, percentage)); }, getValue: function() { if (this.range) { return this.value; } return this.value[0]; }, setValue: function(val) { this.value = val; if (this.range) { this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); } else { this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; this.handle2.addClass('hide'); if (this.selection == 'after') { this.value[1] = this.max; } else { this.value[1] = this.min; } } this.diff = this.max - this.min; this.percentage = [ (this.value[0]-this.min)*100/this.diff, (this.value[1]-this.min)*100/this.diff, this.step*100/this.diff ]; this.layout(); } }; $.fn.slider = function ( option, val ) { return this.each(function () { var $this = $(this), data = $this.data('slider'), options = typeof option === 'object' && option; if (!data) { $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options)))); } if (typeof option == 'string') { data[option](val); } }) }; $.fn.slider.defaults = { min: 0, max: 10, step: 1, orientation: 'horizontal', value: 5, selection: 'before', tooltip: 'show', handle: 'round', formater: function(value) { return value; } }; $.fn.slider.Constructor = Slider; }( window.jQuery ); less/ 0000775 0000000 0000000 00000000000 12240152740 0040761 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard/bootstrap-slider slider.less 0000664 0000000 0000000 00000004275 12240152740 0043143 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard/bootstrap-slider/less /*! * Slider for Bootstrap * * Copyright 2012 Stefan Petre * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * */ .slider { display: inline-block; vertical-align: middle; position: relative; &.slider-horizontal { width: 210px; height: @baseLineHeight; .slider-track { height: @baseLineHeight/2; width: 100%; margin-top: -@baseLineHeight/4; top: 50%; left: 0; } .slider-selection { height: 100%; top: 0; bottom: 0; } .slider-handle { margin-left: -@baseLineHeight/2; margin-top: -@baseLineHeight/4; &.triangle { border-width: 0 @baseLineHeight/2 @baseLineHeight/2 @baseLineHeight/2; width: 0; height: 0; border-bottom-color: #0480be; margin-top: 0; } } } &.slider-vertical { height: 210px; width: @baseLineHeight; .slider-track { width: @baseLineHeight/2; height: 100%; margin-left: -@baseLineHeight/4; left: 50%; top: 0; } .slider-selection { width: 100%; left: 0; top: 0; bottom: 0; } .slider-handle { margin-left: -@baseLineHeight/4; margin-top: -@baseLineHeight/2; &.triangle { border-width: @baseLineHeight/2 0 @baseLineHeight/2 @baseLineHeight/2; width: 1px; height: 1px; border-left-color: #0480be; margin-left: 0; } } } input { display: none; } .tooltip-inner { white-space: nowrap; } } .slider-track { position: absolute; cursor: pointer; #gradient > .vertical(#f5f5f5, #f9f9f9); .box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); .border-radius(@baseBorderRadius); } .slider-selection { position: absolute; #gradient > .vertical(#f9f9f9, #f5f5f5); .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); .box-sizing(border-box); .border-radius(@baseBorderRadius); } .slider-handle { position: absolute; width: @baseLineHeight; height: @baseLineHeight; #gradient > .vertical(#149bdf, #0480be); .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); opacity: 0.8; border: 0px solid transparent; &.round { .border-radius(@baseLineHeight); } &.triangle { background: transparent none; } } slider.css 0000664 0000000 0000000 00000013523 12240152740 0042013 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard/bootstrap-slider /*! * Slider for Bootstrap * * Copyright 2012 Stefan Petre * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * */ .slider { display: inline-block; vertical-align: middle; position: relative; } .slider.slider-horizontal { width: 210px; height: 20px; } .slider.slider-horizontal .slider-track { height: 10px; width: 100%; margin-top: -5px; top: 50%; left: 0; } .slider.slider-horizontal .slider-selection { height: 100%; top: 0; bottom: 0; } .slider.slider-horizontal .slider-handle { margin-left: -10px; margin-top: -5px; } .slider.slider-horizontal .slider-handle.triangle { border-width: 0 10px 10px 10px; width: 0; height: 0; border-bottom-color: #0480be; margin-top: 0; } .slider.slider-vertical { height: 210px; width: 20px; } .slider.slider-vertical .slider-track { width: 10px; height: 100%; margin-left: -5px; left: 50%; top: 0; } .slider.slider-vertical .slider-selection { width: 100%; left: 0; top: 0; bottom: 0; } .slider.slider-vertical .slider-handle { margin-left: -5px; margin-top: -10px; } .slider.slider-vertical .slider-handle.triangle { border-width: 10px 0 10px 10px; width: 1px; height: 1px; border-left-color: #0480be; margin-left: 0; } .slider input { display: none; } .slider .tooltip-inner { white-space: nowrap; } .slider-track { position: absolute; cursor: pointer; background-color: #f7f7f7; background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .slider-selection { position: absolute; background-color: #f7f7f7; background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5)); background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5); background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5); background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0); -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .slider-handle { position: absolute; width: 20px; height: 20px; background-color: #0e90d2; background-image: -moz-linear-gradient(top, #149bdf, #0480be); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); background-image: -webkit-linear-gradient(top, #149bdf, #0480be); background-image: -o-linear-gradient(top, #149bdf, #0480be); background-image: linear-gradient(to bottom, #149bdf, #0480be); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); opacity: 0.8; border: 0px solid transparent; } .slider-handle.round { -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; } .slider-handle.triangle { background: transparent none; } /* custom */ .slider-handle, .slider-handle:hover { background-color: #3071a9; opacity: 1; width: 8px; height: 26px; margin-top: -4px!important; margin-left: -6px !important; border-radius: 0px; -moz-border-radius: 0px; -webkit-border-radius: 0px; text-shadow: 0 1px 0 #fff; background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); background-repeat: repeat-x; border-color: #2d6ca2; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); } .slider-handle:hover { background: #428bca; background-image: none; border-color: #2d6ca2; } .slider-track, .slider-selection { height: 20px !important; background: #ccc; background: -webkit-linear-gradient(top, #bbb, #ddd); background: -moz-linear-gradient(top, #bbb, #ddd); background: linear-gradient(top, #bbb, #ddd); -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; border: 1px solid #aaa; } .slider-selection { background-color: #8DCA09; background: -webkit-linear-gradient(top, #8DCA09, #72A307); background: -moz-linear-gradient(top, #8DCA09, #72A307); background: linear-gradient(top, #8DCA09, #72A307); border-color: #496805; } .vm-slider { width: 300px; } .output { padding-left: 10px; font-weight: bold; } dashboard.css 0000664 0000000 0000000 00000005671 12240152740 0037170 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard /* Move down content because we have a fixed navbar that is 50px tall */ body { padding-top: 50px; padding-bottom: 20px; } /* Set widths on the navbar form inputs since otherwise they're 100% wide */ .navbar-form input[type="text"], .navbar-form input[type="password"] { width: 180px; } /* Wrapping element */ /* Set some basic padding to keep content from hitting the edges */ .body-content { padding-left: 15px; padding-right: 15px; } /* Responsive: Portrait tablets and up */ @media screen and (min-width: 768px) { /* Let the jumbotron breathe */ .container > :first-child { margin-top: 20px; } /* Remove padding from wrapping element since we kick in the grid classes here */ .body-content { padding: 0; } } .no-margin { margin: 0!important; } .list-group .list-group-footer { padding-top: 5px; padding-bottom: 5px; } .big { font-size: 2em; } .bigbig { font-size: 3em; } .timeline { border-left: 4px #428bca solid; margin-left: 20px; padding-left: 20px; } .timeline > div { margin: 0; padding: 0; margin-left: -34px; margin-bottom: .5em; line-height: 24px; } .timeline > div:last-child { margin-bottom: 0; } .timeline .timeline-icon { margin: 0; padding: 0; width: 24px; height: 24px; text-align: center; display: inline-block; border-radius: 50%; background-color: #428bca; color: #fff; } .timeline-icon.timeline-warning { border-color: #c09853; border-style: solid; border-width: 2px; background-color: white; color: #c09853; line-height: 20px; } .timeline .timeline-icon.timeline-nobg { background-color: transparent; } .table-with-form-fields tbody tr td { line-height: 34px; } #vm-detail-panel .panel-body { min-height: 20em; } :link i:before:hover { text-decoration: none !important; } .slider { display: inline-block; } .slider .track { height: 20px; top: 50%; } .slider > .dragger, .slider > .dragger:hover { border-radius: 0px; -moz-border-radius: 0px; -webkit-border-radius: 0px; width: 8px; height: 24px; margin-top: -12px!important; text-shadow: 0 1px 0 #fff; background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); background-repeat: repeat-x; border-color: #2d6ca2; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); } .slider > .dragger:hover { background-color: #3071a9; background-image: none; border-color: #2d6ca2; } .slider > .highlight-track { height: 20px; top: 50%; } .slider + .output { } .rule-table tr >:nth-child(1) { text-align: right; } .rule-table tr >:nth-child(2) { text-align: center; } .dashboard-index .panel { height: 300px; } dashboard.js 0000664 0000000 0000000 00000003757 12240152740 0037017 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard $(function () { $('.vm-create').click(function(e) { $.ajax({ type: 'GET', url: '/dashboard/vm/create/', success: function(data) { $('body').append(data); vmCreateLoaded(); addSliderMiscs(); $('#vm-create-modal').modal('show'); $('#vm-create-modal').on('hidden.bs.modal', function() { $('#vm-create-modal').remove(); }); } }); return false; }); $('[href=#vm-graph-view]').click(function (e) { $('#vm-list-view').hide(); $('#vm-graph-view').show(); $('[href=#vm-list-view]').removeClass('disabled'); $('[href=#vm-graph-view]').addClass('disabled'); e.stopImmediatePropagation(); return false; }); $('[href=#vm-list-view]').click(function (e) { $('#vm-graph-view').hide(); $('#vm-list-view').show(); $('[href=#vm-list-view]').addClass('disabled'); $('[href=#vm-graph-view]').removeClass('disabled'); e.stopImmediatePropagation(); return false; }).addClass('disabled'); $('[title]').tooltip(); $(':input[title]').tooltip({trigger: 'focus', placement: 'auto right'}); $(".knob").knob(); if (window.location.hash) $("a[href=" + window.location.hash +"]").tab('show'); addSliderMiscs(); }); function addSliderMiscs() { $('.vm-slider').each(function() { $("").addClass("output").html($(this).val()).insertAfter($(this)); }); $('.vm-slider').slider() .on('slide', function(e) { $(this).val(e.value); $(this).parent('div').nextAll("span").html(e.value) }); refreshSliders(); } // ehhh function refreshSliders() { $('.vm-slider').each(function() { $(this).val($(this).slider().data('slider').getValue()); $(this).parent('div').nextAll("span").html($(this).val()); }); } js/ 0000775 0000000 0000000 00000000000 12240152740 0035132 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard jquery.knob.js 0000664 0000000 0000000 00000052324 12240152740 0037745 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard/js /*!jQuery Knob*/ /** * Downward compatible, touchable dial * * Version: 1.2.0 (15/07/2012) * Requires: jQuery v1.7+ * * Copyright (c) 2012 Anthony Terrien * Under MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Thanks to vor, eskimoblood, spiffistan, FabrizioC */ (function($) { /** * Kontrol library */ "use strict"; /** * Definition of globals and core */ var k = {}, // kontrol max = Math.max, min = Math.min; k.c = {}; k.c.d = $(document); k.c.t = function (e) { return e.originalEvent.touches.length - 1; }; /** * Kontrol Object * * Definition of an abstract UI control * * Each concrete component must call this one. *
* k.o.call(this);
*
*/
k.o = function () {
var s = this;
this.o = null; // array of options
this.$ = null; // jQuery wrapped element
this.i = null; // mixed HTMLInputElement or array of HTMLInputElement
this.g = null; // 2D graphics context for 'pre-rendering'
this.v = null; // value ; mixed array or integer
this.cv = null; // change value ; not commited value
this.x = 0; // canvas x position
this.y = 0; // canvas y position
this.$c = null; // jQuery canvas element
this.c = null; // rendered canvas context
this.t = 0; // touches index
this.isInit = false;
this.fgColor = null; // main color
this.pColor = null; // previous color
this.dH = null; // draw hook
this.cH = null; // change hook
this.eH = null; // cancel hook
this.rH = null; // release hook
this.scale = 1; // scale factor
this.run = function () {
var cf = function (e, conf) {
var k;
for (k in conf) {
s.o[k] = conf[k];
}
s.init();
s._configure()
._draw();
};
if(this.$.data('kontroled')) return;
this.$.data('kontroled', true);
this.extend();
this.o = $.extend(
{
// Config
min : this.$.data('min') || 0,
max : this.$.data('max') || 100,
stopper : true,
readOnly : this.$.data('readonly'),
// UI
cursor : (this.$.data('cursor') === true && 30)
|| this.$.data('cursor')
|| 0,
thickness : this.$.data('thickness') || 0.35,
lineCap : this.$.data('linecap') || 'butt',
width : this.$.data('width') || 200,
height : this.$.data('height') || 200,
displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
displayPrevious : this.$.data('displayprevious'),
fgColor : this.$.data('fgcolor') || '#87CEEB',
inputColor: this.$.data('inputcolor') || this.$.data('fgcolor') || '#87CEEB',
inline : false,
step : this.$.data('step') || 1,
// Hooks
draw : null, // function () {}
change : null, // function (value) {}
cancel : null, // function () {}
release : null, // function (value) {}
error : null // function () {}
}, this.o
);
// routing value
if(this.$.is('fieldset')) {
// fieldset = array of integer
this.v = {};
this.i = this.$.find('input')
this.i.each(function(k) {
var $this = $(this);
s.i[k] = $this;
s.v[k] = $this.val();
$this.bind(
'change'
, function () {
var val = {};
val[k] = $this.val();
s.val(val);
}
);
});
this.$.find('legend').remove();
} else {
// input = integer
this.i = this.$;
this.v = this.$.val();
(this.v == '') && (this.v = this.o.min);
this.$.bind(
'change'
, function () {
s.val(s._validate(s.$.val()));
}
);
}
(!this.o.displayInput) && this.$.hide();
this.$c = $('');
this.c = this.$c[0].getContext? this.$c[0].getContext('2d') : null;
if (!this.c) {
this.o.error && this.o.error();
return;
}
this.$
.wrap($(''))
.before(this.$c);
this.scale = (window.devicePixelRatio || 1) /
(
this.c.webkitBackingStorePixelRatio ||
this.c.mozBackingStorePixelRatio ||
this.c.msBackingStorePixelRatio ||
this.c.oBackingStorePixelRatio ||
this.c.backingStorePixelRatio || 1
);
if (this.scale !== 1) {
this.$c[0].width = this.$c[0].width * this.scale;
this.$c[0].height = this.$c[0].height * this.scale;
this.$c.width(this.o.width);
this.$c.height(this.o.height);
}
if (this.v instanceof Object) {
this.cv = {};
this.copy(this.v, this.cv);
} else {
this.cv = this.v;
}
this.$
.bind("configure", cf)
.parent()
.bind("configure", cf);
this._listen()
._configure()
._xy()
.init();
this.isInit = true;
this._draw();
return this;
};
this._draw = function () {
// canvas pre-rendering
var d = true,
c = document.createElement('canvas');
c.width = s.o.width * s.scale;
c.height = s.o.height * s.scale;
s.g = c.getContext('2d');
s.clear();
s.dH
&& (d = s.dH());
(d !== false) && s.draw();
s.c.drawImage(c, 0, 0);
c = null;
};
this._touch = function (e) {
var touchMove = function (e) {
var v = s.xy2val(
e.originalEvent.touches[s.t].pageX,
e.originalEvent.touches[s.t].pageY
);
if (v == s.cv) return;
if (
s.cH
&& (s.cH(v) === false)
) return;
s.change(s._validate(v));
s._draw();
};
// get touches index
this.t = k.c.t(e);
// First touch
touchMove(e);
// Touch events listeners
k.c.d
.bind("touchmove.k", touchMove)
.bind(
"touchend.k"
, function () {
k.c.d.unbind('touchmove.k touchend.k');
if (
s.rH
&& (s.rH(s.cv) === false)
) return;
s.val(s.cv);
}
);
return this;
};
this._mouse = function (e) {
var mouseMove = function (e) {
var v = s.xy2val(e.pageX, e.pageY);
if (v == s.cv) return;
if (
s.cH
&& (s.cH(v) === false)
) return;
s.change(s._validate(v));
s._draw();
};
// First click
mouseMove(e);
// Mouse events listeners
k.c.d
.bind("mousemove.k", mouseMove)
.bind(
// Escape key cancel current change
"keyup.k"
, function (e) {
if (e.keyCode === 27) {
k.c.d.unbind("mouseup.k mousemove.k keyup.k");
if (
s.eH
&& (s.eH() === false)
) return;
s.cancel();
}
}
)
.bind(
"mouseup.k"
, function (e) {
k.c.d.unbind('mousemove.k mouseup.k keyup.k');
if (
s.rH
&& (s.rH(s.cv) === false)
) return;
s.val(s.cv);
}
);
return this;
};
this._xy = function () {
var o = this.$c.offset();
this.x = o.left;
this.y = o.top;
return this;
};
this._listen = function () {
if (!this.o.readOnly) {
this.$c
.bind(
"mousedown"
, function (e) {
e.preventDefault();
s._xy()._mouse(e);
}
)
.bind(
"touchstart"
, function (e) {
e.preventDefault();
s._xy()._touch(e);
}
);
this.listen();
} else {
this.$.attr('readonly', 'readonly');
}
return this;
};
this._configure = function () {
// Hooks
if (this.o.draw) this.dH = this.o.draw;
if (this.o.change) this.cH = this.o.change;
if (this.o.cancel) this.eH = this.o.cancel;
if (this.o.release) this.rH = this.o.release;
if (this.o.displayPrevious) {
this.pColor = this.h2rgba(this.o.fgColor, "0.4");
this.fgColor = this.h2rgba(this.o.fgColor, "0.6");
} else {
this.fgColor = this.o.fgColor;
}
return this;
};
this._clear = function () {
this.$c[0].width = this.$c[0].width;
};
this._validate = function(v) {
return (~~ (((v < 0) ? -0.5 : 0.5) + (v/this.o.step))) * this.o.step;
};
// Abstract methods
this.listen = function () {}; // on start, one time
this.extend = function () {}; // each time configure triggered
this.init = function () {}; // each time configure triggered
this.change = function (v) {}; // on change
this.val = function (v) {}; // on release
this.xy2val = function (x, y) {}; //
this.draw = function () {}; // on change / on release
this.clear = function () { this._clear(); };
// Utils
this.h2rgba = function (h, a) {
var rgb;
h = h.substring(1,7)
rgb = [parseInt(h.substring(0,2),16)
,parseInt(h.substring(2,4),16)
,parseInt(h.substring(4,6),16)];
return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
};
this.copy = function (f, t) {
for (var i in f) { t[i] = f[i]; }
};
};
/**
* k.Dial
*/
k.Dial = function () {
k.o.call(this);
this.startAngle = null;
this.xy = null;
this.radius = null;
this.lineWidth = null;
this.cursorExt = null;
this.w2 = null;
this.PI2 = 2*Math.PI;
this.extend = function () {
this.o = $.extend(
{
bgColor : this.$.data('bgcolor') || '#EEEEEE',
angleOffset : this.$.data('angleoffset') || 0,
angleArc : this.$.data('anglearc') || 360,
inline : true
}, this.o
);
};
this.val = function (v) {
if (null != v) {
this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;
this.v = this.cv;
this.$.val(this.v);
this._draw();
} else {
return this.v;
}
};
this.xy2val = function (x, y) {
var a, ret;
a = Math.atan2(
x - (this.x + this.w2)
, - (y - this.y - this.w2)
) - this.angleOffset;
if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {
// if isset angleArc option, set to min if .5 under min
a = 0;
} else if (a < 0) {
a += this.PI2;
}
ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc))
+ this.o.min;
this.o.stopper
&& (ret = max(min(ret, this.o.max), this.o.min));
return ret;
};
this.listen = function () {
// bind MouseWheel
var s = this,
mw = function (e) {
e.preventDefault();
var ori = e.originalEvent
,deltaX = ori.detail || ori.wheelDeltaX
,deltaY = ori.detail || ori.wheelDeltaY
,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? s.o.step : deltaX<0 || deltaY<0 ? -s.o.step : 0);
if (
s.cH
&& (s.cH(v) === false)
) return;
s.val(v);
}
, kval, to, m = 1, kv = {37:-s.o.step, 38:s.o.step, 39:s.o.step, 40:-s.o.step};
this.$
.bind(
"keydown"
,function (e) {
var kc = e.keyCode;
// numpad support
if(kc >= 96 && kc <= 105) {
kc = e.keyCode = kc - 48;
}
kval = parseInt(String.fromCharCode(kc));
if (isNaN(kval)) {
(kc !== 13) // enter
&& (kc !== 8) // bs
&& (kc !== 9) // tab
&& (kc !== 189) // -
&& e.preventDefault();
// arrows
if ($.inArray(kc,[37,38,39,40]) > -1) {
e.preventDefault();
var v = parseInt(s.$.val()) + kv[kc] * m;
s.o.stopper
&& (v = max(min(v, s.o.max), s.o.min));
s.change(v);
s._draw();
// long time keydown speed-up
to = window.setTimeout(
function () { m*=2; }
,30
);
}
}
}
)
.bind(
"keyup"
,function (e) {
if (isNaN(kval)) {
if (to) {
window.clearTimeout(to);
to = null;
m = 1;
s.val(s.$.val());
}
} else {
// kval postcond
(s.$.val() > s.o.max && s.$.val(s.o.max))
|| (s.$.val() < s.o.min && s.$.val(s.o.min));
}
}
);
this.$c.bind("mousewheel DOMMouseScroll", mw);
this.$.bind("mousewheel DOMMouseScroll", mw)
};
this.init = function () {
if (
this.v < this.o.min
|| this.v > this.o.max
) this.v = this.o.min;
this.$.val(this.v);
this.w2 = this.o.width / 2;
this.cursorExt = this.o.cursor / 100;
this.xy = this.w2 * this.scale;
this.lineWidth = this.xy * this.o.thickness;
this.lineCap = this.o.lineCap;
this.radius = this.xy - this.lineWidth / 2;
this.o.angleOffset
&& (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);
this.o.angleArc
&& (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);
// deg to rad
this.angleOffset = this.o.angleOffset * Math.PI / 180;
this.angleArc = this.o.angleArc * Math.PI / 180;
// compute start and end angles
this.startAngle = 1.5 * Math.PI + this.angleOffset;
this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;
var s = max(
String(Math.abs(this.o.max)).length
, String(Math.abs(this.o.min)).length
, 2
) + 2;
this.o.displayInput
&& this.i.css({
'width' : ((this.o.width / 2 + 4) >> 0) + 'px'
,'height' : ((this.o.width / 3) >> 0) + 'px'
,'position' : 'absolute'
,'vertical-align' : 'middle'
,'margin-top' : ((this.o.width / 3) >> 0) + 'px'
,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px'
,'border' : 0
,'background' : 'none'
,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial'
,'text-align' : 'center'
,'color' : this.o.inputColor || this.o.fgColor
,'padding' : '0px'
,'-webkit-appearance': 'none'
})
|| this.i.css({
'width' : '0px'
,'visibility' : 'hidden'
});
};
this.change = function (v) {
this.cv = v;
this.$.val(v);
};
this.angle = function (v) {
return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);
};
this.draw = function () {
var c = this.g, // context
a = this.angle(this.cv) // Angle
, sat = this.startAngle // Start angle
, eat = sat + a // End angle
, sa, ea // Previous angles
, r = 1;
c.lineWidth = this.lineWidth;
c.lineCap = this.lineCap;
this.o.cursor
&& (sat = eat - this.cursorExt)
&& (eat = eat + this.cursorExt);
c.beginPath();
c.strokeStyle = this.o.bgColor;
c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true);
c.stroke();
if (this.o.displayPrevious) {
ea = this.startAngle + this.angle(this.v);
sa = this.startAngle;
this.o.cursor
&& (sa = ea - this.cursorExt)
&& (ea = ea + this.cursorExt);
c.beginPath();
c.strokeStyle = this.pColor;
c.arc(this.xy, this.xy, this.radius, sa, ea, false);
c.stroke();
r = (this.cv == this.v);
}
c.beginPath();
c.strokeStyle = r ? this.o.fgColor : this.fgColor ;
c.arc(this.xy, this.xy, this.radius, sat, eat, false);
c.stroke();
};
this.cancel = function () {
this.val(this.v);
};
};
$.fn.dial = $.fn.knob = function (o) {
return this.each(
function () {
var d = new k.Dial();
d.o = o;
d.$ = $(this);
d.run();
}
).parent();
};
})(jQuery); loopj-jquery-simple-slider-fa64f59/ 0000775 0000000 0000000 00000000000 12240152740 0043007 5 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard loopj-jquery-simple-slider-fa64f59/.gitignore 0000664 0000000 0000000 00000000034 12240152740 0044774 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard node_modules/
*.zip
gh-pages loopj-jquery-simple-slider-fa64f59/README.md 0000664 0000000 0000000 00000001302 12240152740 0044262 0 ustar 00root root 0000000 0000000 cloud-e67366887fe6df96d33ccef18c937edfcaae8a35-e67366887fe6df96d33ccef18c937edfcaae8a35/circle/dashboard/static/dashboard jQuery Simple Slider: Unobtrusive Numerical Slider
==================================================
SimpleSlider is a jQuery plugin for turning your text inputs into draggable
numerical sliders.
It has no external dependencies other than jQuery, and you don't need to write
a single line of JavaScript to get it to work.
How to Use
-----------
Include the javascript file in your page:
Turn your text input into a slider:
Documentation, Features and Demos
---------------------------------
Full details and documentation can be found on the project page here: