pax_global_header 0000666 0000000 0000000 00000000064 12225257661 0014522 g ustar 00root root 0000000 0000000 52 comment=7a61fb2f8a676e09498eff3337141905a13559fe cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/ 0000775 0000000 0000000 00000000000 12225257661 0024702 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/.gitignore 0000664 0000000 0000000 00000000257 12225257661 0026676 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 CONTRIBUTORS.txt 0000664 0000000 0000000 00000000141 12225257661 0027315 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe Adam Dudas Bence Danyi Daniel Bach Gergo Nagy Imre Szeberenyi Mate Ory Sandor Guba Viktor Kalman cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/LICENSE.txt 0000664 0000000 0000000 00000000206 12225257661 0026523 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-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/README.rst 0000664 0000000 0000000 00000000163 12225257661 0026371 0 ustar 00root root 0000000 0000000 ============= cirecle-cloud ============= This is the Django based controller and web portal of the CIRCLE Cloud. cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/ 0000775 0000000 0000000 00000000000 12225257661 0026143 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000000000 12225257661 0030163 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle circle/ 0000775 0000000 0000000 00000000000 12225257661 0027325 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle __init__.py 0000664 0000000 0000000 00000000000 12225257661 0031424 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/circle settings/ 0000775 0000000 0000000 00000000000 12225257661 0031165 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/circle __init__.py 0000664 0000000 0000000 00000000001 12225257661 0033265 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/circle/settings base.py 0000664 0000000 0000000 00000022656 12225257661 0032464 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/circle/settings """Common settings and globals.""" 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', ) # Apps specific for this project go here. LOCAL_APPS = ( 'vm', 'storage', 'firewall', 'network', 'dashboard', 'manager', ) # 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' from datetime import timedelta CELERYBEAT_SCHEDULE = { 'blabla': { 'task': 'firewall.tasks.local_tasks.periodic_task', 'schedule': timedelta(seconds=5), }, } local.py 0000664 0000000 0000000 00000003703 12225257661 0032634 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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 production.py 0000664 0000000 0000000 00000004533 12225257661 0033732 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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 00000000656 12225257661 0032525 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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": "", }, } urls.py 0000664 0000000 0000000 00000001123 12225257661 0030661 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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')), ) wsgi.py 0000664 0000000 0000000 00000003421 12225257661 0030650 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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) dashboard/ 0000775 0000000 0000000 00000000000 12225257661 0030013 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle __init__.py 0000664 0000000 0000000 00000000000 12225257661 0032112 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard models.py 0000664 0000000 0000000 00000000071 12225257661 0031646 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard from django.db import models # Create your models here. static/ 0000775 0000000 0000000 00000000000 12225257661 0031302 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard dashboard/ 0000775 0000000 0000000 00000000000 12225257661 0033231 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard/static dashboard.css 0000664 0000000 0000000 00000005671 12225257661 0035703 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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 00000006276 12225257661 0035531 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard/static/dashboard $(function () { $('.vm-create').click(function(e) { $.ajax({ type: 'GET', url: '/dashboard/vm/create/', success: function(data) { // TODO this is still ugly var html = '
* 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 12225257661 0041522 5 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard/static/dashboard loopj-jquery-simple-slider-fa64f59/.gitignore 0000664 0000000 0000000 00000000034 12225257661 0043507 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/circle/dashboard/static/dashboard node_modules/
*.zip
gh-pages loopj-jquery-simple-slider-fa64f59/README.md 0000664 0000000 0000000 00000001302 12225257661 0042775 0 ustar 00root root 0000000 0000000 cloud-7a61fb2f8a676e09498eff3337141905a13559fe-7a61fb2f8a676e09498eff3337141905a13559fe/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: