├── cmdb ├── __init__.py ├── templatetags │ ├── __init__.py │ └── cmdb_tags.py ├── tests.py ├── context_processors.py ├── cmdb_menu.py ├── model_form.py ├── models.py └── base_admin.py ├── myproject ├── __init__.py ├── wsgi.py ├── urls.py ├── api.py └── settings.py ├── echelon ├── templatetags │ ├── __init__.py │ └── echelon_changelog.py ├── __init__.py ├── urls.py ├── middleware.py ├── fields.py └── views.py ├── static ├── plugins │ ├── fuelux-3.11.0 │ │ ├── CNAME │ │ ├── markup │ │ │ ├── infinite-scroll.html │ │ │ ├── loader.html │ │ │ ├── combobox-variations.txt │ │ │ ├── pillbox-variations.txt │ │ │ ├── wizard-variations.txt │ │ │ ├── spinbox-variations.txt │ │ │ ├── placard.html │ │ │ ├── repeater-variations.txt │ │ │ ├── checkbox-inline.html │ │ │ ├── radio-inline.html │ │ │ ├── selectlist-variations.txt │ │ │ ├── radio.html │ │ │ ├── checkbox.html │ │ │ ├── placard-variations.txt │ │ │ ├── radio-no-js.html │ │ │ ├── checkbox-no-js.html │ │ │ ├── radio-inline-no-js.html │ │ │ ├── checkbox-inline-no-js.html │ │ │ ├── search.html │ │ │ ├── placard-header-footer.html │ │ │ ├── loader-variations.txt │ │ │ ├── radio-variations.txt │ │ │ ├── checkbox-variations.txt │ │ │ ├── spinbox.html │ │ │ ├── checkbox-no-js-variations.txt │ │ │ ├── pillbox.html │ │ │ ├── radio-no-js-variations.txt │ │ │ ├── combobox.html │ │ │ ├── selectlist.html │ │ │ ├── tree.html │ │ │ ├── tree-folders-selectable.html │ │ │ ├── pillbox-with-pills.html │ │ │ └── datepicker.html │ │ ├── test │ │ │ ├── markup │ │ │ │ ├── loader-markup.html │ │ │ │ ├── infinite-scroll-markup.html │ │ │ │ ├── search-markup.html │ │ │ │ ├── placard-markup.html │ │ │ │ ├── checkbox-markup.html │ │ │ │ ├── radio-markup.html │ │ │ │ ├── pillbox-markup.html │ │ │ │ ├── spinbox-markup.html │ │ │ │ ├── tree-markup.html │ │ │ │ ├── combobox-markup.html │ │ │ │ └── datepicker-markup.html │ │ │ ├── commonjs.html │ │ │ ├── tests-no-moment.js │ │ │ ├── browser-globals.html │ │ │ ├── tests.js │ │ │ ├── commonjs-test.js │ │ │ ├── loader-test.js │ │ │ └── browser-globals.js │ │ ├── Procfile │ │ ├── dist │ │ │ ├── fuelux.zip │ │ │ ├── fonts │ │ │ │ ├── fuelux.eot │ │ │ │ ├── fuelux.ttf │ │ │ │ ├── fuelux.woff │ │ │ │ └── fuelux.svg │ │ │ └── js │ │ │ │ └── npm.js │ │ ├── fonts │ │ │ ├── fuelux.eot │ │ │ ├── fuelux.ttf │ │ │ ├── fuelux.woff │ │ │ ├── src │ │ │ │ ├── bullet.svg │ │ │ │ ├── loader_full.svg │ │ │ │ ├── loader_7.svg │ │ │ │ ├── loader_1.svg │ │ │ │ ├── loader_5.svg │ │ │ │ ├── loader_8.svg │ │ │ │ ├── loader_3.svg │ │ │ │ ├── loader_4.svg │ │ │ │ ├── loader_6.svg │ │ │ │ └── loader_2.svg │ │ │ └── fuelux.svg │ │ ├── postinstall.sh │ │ ├── less │ │ │ ├── intelligent-dropdown.less │ │ │ ├── search.less │ │ │ ├── combobox.less │ │ │ ├── infinite-scroll.less │ │ │ ├── checkbox-no-js.less │ │ │ ├── loader.less │ │ │ ├── selectlist.less │ │ │ ├── fuelux.less │ │ │ ├── spinbox.less │ │ │ ├── repeater-thumbnail.less │ │ │ ├── radio-no-js.less │ │ │ ├── repeater.less │ │ │ ├── checkbox.less │ │ │ ├── pillbox.less │ │ │ ├── icons.less │ │ │ ├── radio.less │ │ │ ├── placard.less │ │ │ ├── mixins.less │ │ │ ├── tree.less │ │ │ └── utility.less │ │ ├── BACKLOG.md │ │ ├── devserver.js │ │ ├── .travis.yml │ │ ├── index.css │ │ ├── .gitignore │ │ ├── grunt │ │ │ └── commonjs-reference-module.js │ │ ├── .bithoundrc │ │ ├── bower.json │ │ ├── js │ │ │ └── all.js │ │ ├── sauce_browsers.yml │ │ ├── LICENSE │ │ ├── sauce_browsers_tricky.yml │ │ ├── dev │ │ │ └── dev.html.example │ │ └── package.json │ └── datetimepicker │ │ └── js │ │ └── locales │ │ ├── bootstrap-datetimepicker.zh-CN.js │ │ ├── bootstrap-datetimepicker.zh-TW.js │ │ ├── bootstrap-datetimepicker.ua.js │ │ └── bootstrap-datetimepicker.uk.js └── bootstrap-3.3.5-dist │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 │ └── js │ └── npm.js ├── utils ├── __init__.py └── constant.py ├── templates ├── home.html ├── logout.html ├── 404.html ├── echelon │ └── changelog_detail.html ├── cmdb │ └── widgets │ │ ├── checkbox.html │ │ ├── div.html │ │ ├── pre.html │ │ ├── json.html │ │ ├── password.html │ │ ├── textarea.html │ │ ├── typeahead.html │ │ ├── editor.html │ │ ├── revenumerate.html │ │ ├── input.html │ │ ├── enumerate_read_only.html │ │ ├── enumerate.html │ │ ├── multiselect2.html │ │ ├── datetime.html │ │ └── file.html ├── base │ ├── base.html │ └── base_bootstrap.html ├── rest_framework │ └── api.html ├── login.html └── add_modify.html ├── requirements.txt ├── manage.py ├── README.md └── local_settings.py /cmdb/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /myproject/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmdb/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /echelon/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /echelon/__init__.py: -------------------------------------------------------------------------------- 1 | __version__= (1,1) 2 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/CNAME: -------------------------------------------------------------------------------- 1 | getfuelux.com 2 | -------------------------------------------------------------------------------- /cmdb/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 把所有框架代码都移到utils中, 用户拿到代码后不必关心utils中的实现 -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/infinite-scroll.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/loader.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/loader-markup.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/Procfile: -------------------------------------------------------------------------------- 1 | web: tar -zcf dev/node_modules.tar.gz node_modules/ && grunt dist && node devserver.js -------------------------------------------------------------------------------- /echelon/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns 2 | 3 | urlpatterns = patterns('echelon.views', ('^$', 'changelog'), ) -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/fuelux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/dist/fuelux.zip -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/fuelux.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/fonts/fuelux.eot -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/fuelux.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/fonts/fuelux.ttf -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/fuelux.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/fonts/fuelux.woff -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/fonts/fuelux.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/dist/fonts/fuelux.eot -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/fonts/fuelux.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/dist/fonts/fuelux.ttf -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/fonts/fuelux.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/plugins/fuelux-3.11.0/dist/fonts/fuelux.woff -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/infinite-scroll-markup.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base/base.html" %} 2 | {% block title %} 3 | Home 4 | {% endblock %} 5 | {% block content %} 6 | {% endblock %} 7 | 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==1.7.1 2 | MySQL-python>=1.2.5 3 | PyYAML>=3.12 4 | IPy 5 | djangorestframework==3.3.1 6 | markdown==2.6.7 7 | django-filter==0.11.0 8 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/postinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$INSTALL_BOWER" = "true" ]; then 4 | node ./node_modules/bower/bin/bower install 5 | fi -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/combobox-variations.txt: -------------------------------------------------------------------------------- 1 | //Has selected item upon initialization 2 | - add 'data-selected="true"' to desired 'ul.dropdown-menu li' tag -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/pillbox-variations.txt: -------------------------------------------------------------------------------- 1 | //Read Only 2 | - can be set via options, or by adding 'data-readonly="readonly"' to 'pillbox' classed div -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/wizard-variations.txt: -------------------------------------------------------------------------------- 1 | //Active step 2 | - add class 'active' to 'ul.steps li' element of choice to make that step active upon initialization -------------------------------------------------------------------------------- /static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/spinbox-variations.txt: -------------------------------------------------------------------------------- 1 | //Has default value to begin with 2 | - add 'value="{{string}}"' to input classed 'spinbox-input' 3 | (ex: 'value="10"') -------------------------------------------------------------------------------- /static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyu/open-cmdb/HEAD/static/bootstrap-3.3.5-dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/placard.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
-------------------------------------------------------------------------------- /templates/logout.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% block title %}{% trans "Sign Out" %}{% endblock %} 3 | {% block content %} 4 |
5 |

{% trans "Successful log out" %}

6 |
7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/repeater-variations.txt: -------------------------------------------------------------------------------- 1 | //Static height 2 | - add 'data-staticheight="{{string}}"' to element classed '.repeater' to set the repeater's height 3 | (ex: 'data-staticheight="400"' or 'data-staticheight="true") -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox-inline.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio-inline.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/selectlist-variations.txt: -------------------------------------------------------------------------------- 1 | //Has selected item upon initialization 2 | - add 'data-selected="true"' to desired 'ul.dropdown-menu li' tag 3 | 4 | //Auto resizing 5 | - add 'data-resize="auto"' to 'selectlist' classed element -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/intelligent-dropdown.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .dropUp { 4 | -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 5 | -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 6 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base/base.html" %} 2 | {% block title %} 3 | Not Found 4 | {% endblock %} 5 | 6 | {% block content %} 7 |

Page not found

8 | 9 |

Sorry, but the requested page could not be found.

10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /echelon/templatetags/echelon_changelog.py: -------------------------------------------------------------------------------- 1 | from django.template import Library 2 | register = Library() 3 | 4 | @register.inclusion_tag('echelon/changelog_detail.html') 5 | def changelog_detail(changes): 6 | changes = changes.items() 7 | return {'changes': changes} 8 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/search.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .search { 4 | &.disabled { 5 | .input-group-btn { 6 | cursor: not-allowed; 7 | } 8 | } 9 | input { 10 | &::-ms-clear { 11 | display:none; 12 | } 13 | } 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/combobox.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .combobox { 4 | &.disabled { 5 | .input-group-btn { 6 | cursor: not-allowed; 7 | } 8 | } 9 | input { 10 | &::-ms-clear { 11 | display:none; 12 | } 13 | } 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio.html: -------------------------------------------------------------------------------- 1 |
2 | 6 |
-------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox.html: -------------------------------------------------------------------------------- 1 |
2 | 6 |
-------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/placard-variations.txt: -------------------------------------------------------------------------------- 1 | //Text area placard 2 | - replace input element classed '.placard-field' with the following: 3 | '' 4 | 5 | //Glass styling 6 | - add the class 'glass' to the '.placard-field' element -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio-no-js.html: -------------------------------------------------------------------------------- 1 |
2 | 8 | 11 |
12 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox-no-js.html: -------------------------------------------------------------------------------- 1 |
2 | 8 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio-inline-no-js.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | 12 |
13 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox-inline-no-js.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | 12 |
13 | -------------------------------------------------------------------------------- /templates/echelon/changelog_detail.html: -------------------------------------------------------------------------------- 1 | 2 | {% for item in changes %} 3 | 4 | 5 | 6 | 7 | 8 | {% endfor %} 9 |
{{ item.0 }}{{ item.1.0 }}{{ item.1.1 }}
10 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/search-markup.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmdb/context_processors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding:utf8 3 | 4 | from django.conf import settings 5 | from cmdb_menu import CMDB_TOP_MENU 6 | import base_admin 7 | 8 | def menu(request): 9 | return { 10 | 'cmdb_menu': CMDB_TOP_MENU, 11 | 'cmdb_name': settings.CMDB_NAME, 12 | 'cmdb_verison': settings.CMDB_VERSION, 13 | 'base_admin': base_admin.BASE_ADMIN 14 | } 15 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/search.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/BACKLOG.md: -------------------------------------------------------------------------------- 1 | BACKLOG 2 | ======= 3 | 4 | This is a summary of changes under consideration. Please also review the Roadmap at https://github.com/ExactTarget/fuelux/issues?milestone=3&page=1&state=open 5 | 6 | 7 | Under consideration 8 | ------------------- 9 | 10 | * **Colorpicker** - Choose a HEX color from possibly a list or a hue/saturation map 11 | * **"SuperTabs"** - Tab navigation with dynamic description/status on each tab -------------------------------------------------------------------------------- /myproject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myproject project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/placard-header-footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Header
4 | 5 | 9 |
-------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/devserver.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var connect = require('connect'); 3 | var serveStatic = require('serve-static'); 4 | var path = require('path'); 5 | 6 | var port = 9000; 7 | var app = connect(); 8 | 9 | // parent folder 10 | app.use(serveStatic(path.resolve(__dirname))); 11 | 12 | // Listen 13 | app.listen(process.env.PORT || port); 14 | util.puts('Listening on ' + (process.env.PORT || port) + '...'); 15 | util.puts('Press Ctrl + C to stop.'); -------------------------------------------------------------------------------- /static/bootstrap-3.3.5-dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/loader-variations.txt: -------------------------------------------------------------------------------- 1 | //Starting frame 2 | - add 'data-frame="{{number}}"' to 'loader' classed div. 3 | (ex: 'data-frame="5"') 4 | 5 | //Controlling speed (default is 150) 6 | - add 'data-delay="{{milliseconds}}"' to 'loader' classed div 7 | (ex: 'data-delay="500"') 8 | 9 | //Animation range 10 | - add 'data-begin="{{number}}"' to 'loader' classed div to specify beginning frame 11 | (ex: 'data-begin="3"') 12 | - add 'data-end="{{number}}"' to 'loader' classed div to specify ending frame 13 | (ex: 'data-end="6"') -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/infinite-scroll.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .infinitescroll { 4 | overflow-y: auto; 5 | 6 | .infinitescroll-end { 7 | clear: both; 8 | font-style: italic; 9 | padding: 6px; 10 | text-align: center; 11 | } 12 | 13 | .infinitescroll-load { 14 | clear: both; 15 | padding: 6px; 16 | 17 | button { 18 | padding: 5px 12px; 19 | width: 100%; 20 | } 21 | 22 | .loader { 23 | font-size: 32px; 24 | height: 32px; 25 | margin: 0 auto; 26 | width: 32px; 27 | } 28 | } 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/bullet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio-variations.txt: -------------------------------------------------------------------------------- 1 | //Checked when initialized: 2 | - add 'checked' class to input 3 | - add 'checked="checked"' attribute to input 4 | 5 | //Disabled when initialized: 6 | - add 'disabled="disabled"' attribute to input 7 | 8 | //Toggling radios: 9 | - add 'data-toggle="{{selector}}"' attribute to input. This will toggle the matching selector's visibility on check / uncheck 10 | (ex: 'data-toggle="#myTogglingBox"') 11 | 12 | //Highlighting radios: 13 | - add 'highlight' class to block wrapper or label for inline. This will highlight the radio on check / uncheck. -------------------------------------------------------------------------------- /templates/cmdb/widgets/checkbox.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
4 |
5 | 13 |
14 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox-variations.txt: -------------------------------------------------------------------------------- 1 | //Checked when initialized: 2 | - add 'checked' class to input 3 | - add 'checked="checked"' attribute to input 4 | 5 | //Disabled when initialized: 6 | - add 'disabled="disabled"' attribute to input 7 | 8 | //Toggling checkboxes: 9 | - add 'data-toggle="{{selector}}"' attribute to input. This will toggle the matching selector's visibility on check / uncheck 10 | (ex: 'data-toggle="#myTogglingBox"') 11 | 12 | //Highlighting checkboxes: 13 | - add 'highlight' class to block wrapper or label for inline. This will highlight the checkbox on check / uncheck. -------------------------------------------------------------------------------- /cmdb/cmdb_menu.py: -------------------------------------------------------------------------------- 1 | #encoding:utf8 2 | # 菜单配置 3 | CMDB_TOP_MENU = [ 4 | [u'主机管理', '/cmdb/server_device/show/', 'globe', []], 5 | [u'IDC管理', '/cmdb/idc/show/', 'th-list', []], 6 | [u'项目管理', '/cmdb/project/show/', 'credit-card', []], 7 | [u'项目组管理', '/cmdb/server_group/show/', 'tasks', []], 8 | [u'角色管理', '/cmdb/server_role/show/', 'home', []], 9 | [u'用户管理', '/cmdb/user/show/', 'user', []], 10 | [u'用户组管理', '/cmdb/group/show/', 'list', []], 11 | [u'权限管理', '/cmdb/permission/show/', 'asterisk', []], 12 | [u'操作历史', '/cmdb/changelog/', 'time', []], 13 | [u'API文档', '/api/', 'book', []], 14 | ] 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 3 | Open-cmdb是基于Python2.7、Django1.7、Puppet开发的一套快速将服务器软硬件等信息集中化展示的系统。 4 | 5 | 代码比较简单,开发初衷主要是为了方便快速展示Puppet收集上来的所有服务器信息。 6 | 7 | > 主要功能有: 8 | > * 快速展示服务器信息 9 | > * 支持服务器信息录入 10 | 11 | 如果环境中已有Puppet,此系统能快速接入,否则需要自行配置Puppet环境。目前暂时不支持Ansible的YAML格式。 12 | 13 | ## 环境依赖 14 | 15 | * Python2.7 16 | * Django1.7 17 | 18 | 你可以通过此[手册](https://github.com/oysterclub/open-cmdb/wiki/Cetnos6-Installing-Python2.7)完成基础环境配置 19 | 20 | 你可以通过[官方手册](https://github.com/oysterclub/open-cmdb/wiki)快速构建此系统 21 | 22 | 关于此系统更详细的介绍,可以参考书籍:《运维前线》[豆瓣介绍](https://read.douban.com/ebook/30348001/) 23 | 24 | ## 讨论 25 | 26 | 如果大家有什么疑问,欢迎提 #issue 27 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/commonjs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FuelUX Component Initialization (via CommonJS) 6 | 7 | 8 | 9 |

Fuel UX CommonJS Test Suite

10 | 11 |

12 | 13 |
14 |

15 |
    16 |
    17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/spinbox.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 7 | 10 |
    11 |
    -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/checkbox-no-js-variations.txt: -------------------------------------------------------------------------------- 1 | // Checked on page load: 2 | - add 'checked="checked"' attribute to input 3 | 4 | // Disabled on page load: 5 | - add 'disabled="disabled"' attribute to input 6 | 7 | // Toggling with checkboxes uses plain old Bootstrap Collapse: 8 | - See: http://getbootstrap.com/javascript/#collapse 9 | - add `data-toggle="collapse"` 10 | - add `data-target="{{selector}}"` 11 | - optionally consider adding aria attributes `aria-expanded` and `aria-controls` 12 | 13 | // Highlighting checkboxes: 14 | - add 'highlight' class to the `.checkbox` or `.checkbox-inline` wrapper. This will highlight the checkbox on check / uncheck. -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/pillbox.html: -------------------------------------------------------------------------------- 1 |
    2 | 13 |
    -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/radio-no-js-variations.txt: -------------------------------------------------------------------------------- 1 | // Checked on page load: 2 | - add 'checked="checked"' attribute to input 3 | 4 | // Disabled on page load: 5 | - add 'disabled="disabled"' attribute to input 6 | 7 | // Toggling with radio buttons uses plain old Bootstrap Collapse: 8 | - See: http://getbootstrap.com/javascript/#collapse 9 | - add `data-toggle="collapse"` 10 | - add `data-target="{{selector}}"` 11 | - optionally consider adding aria attributes `aria-expanded` and `aria-controls` 12 | 13 | // Highlighting radio buttons: 14 | - add 'highlight' class to the `.radio` or `.radio-inline` wrapper. This will highlight the radio buttons on check / uncheck. 15 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/div.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 |
    3 |
    {{data|getitem:mname|getitem:"verbose_name"|capfirst}}:
    5 |
    6 |
    {{data|getitem:mname|getitem:"value"}}
    8 |
    9 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 10 |
    11 |
    12 | {{data|getitem:mname|getitem:"errormsg"|safe}} 13 |
    14 |
    15 |
    16 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/pre.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 |
    3 | 6 |
    7 |
    {{data|getitem:mname|getitem:"value"}}
    9 |
    10 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 11 |
    12 |
    13 | {{data|getitem:mname|getitem:"errormsg"|safe}} 14 |
    15 |
    16 |
    17 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/json.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 |
    3 |
    {{data|getitem:mname|getitem:"verbose_name"|capfirst}}:
    5 |
    6 |
    {{data|getitem:mname|getitem:"value"|jsonify|safe}}
    8 |
    9 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 10 |
    11 |
    12 | {{data|getitem:mname|getitem:"errormsg"|safe}} 13 |
    14 |
    15 |
    16 | -------------------------------------------------------------------------------- /static/plugins/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Simplified Chinese translation for bootstrap-datetimepicker 3 | * Yuan Cheung 4 | */ 5 | ;(function($){ 6 | $.fn.datetimepicker.dates['zh-CN'] = { 7 | days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], 8 | daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], 9 | daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], 10 | months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], 11 | monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], 12 | today: "今天", 13 | suffix: [], 14 | meridiem: ["上午", "下午"] 15 | }; 16 | }(jQuery)); -------------------------------------------------------------------------------- /static/plugins/datetimepicker/js/locales/bootstrap-datetimepicker.zh-TW.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Traditional Chinese translation for bootstrap-datetimepicker 3 | * Rung-Sheng Jang 4 | */ 5 | ;(function($){ 6 | $.fn.datetimepicker.dates['zh-TW'] = { 7 | days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], 8 | daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], 9 | daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], 10 | months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], 11 | monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], 12 | today: "今天", 13 | suffix: [], 14 | meridiem: ["上午", "下午"] 15 | }; 16 | }(jQuery)); 17 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/combobox.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /utils/constant.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 字段类型与HTML控件的对应关系; 注意,如果model中有用到到新的类型,此处必须添加对应项 4 | FIELD_WIDGETS = { 5 | "ForeignKey": "enumerate", 6 | "OneToOneField": "enumerate", 7 | "ManyToManyField": "multiselect2", 8 | 9 | "CharField": "input", 10 | "SlugField": "input", 11 | "TextField": "textarea", 12 | "GenericIPAddressField": "input", 13 | 14 | "AutoField": "input", 15 | "BooleanField": "checkbox", 16 | "SmallIntegerField": "input", 17 | "BigIntegerField": "input", 18 | "DecimalField": "input", 19 | "EmailField": "input", 20 | "DateField": "datetime", 21 | "DateTimeField": "datetime", 22 | 23 | } 24 | 25 | FOREIGNKEY_FUNCS = ['__foreign_unicode__', 26 | '__unicode__'] -------------------------------------------------------------------------------- /static/plugins/datetimepicker/js/locales/bootstrap-datetimepicker.ua.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ukrainian translation for bootstrap-datepicker 3 | * Igor Polynets 4 | */ 5 | ;(function($){ 6 | $.fn.datetimepicker.dates['ua'] = { 7 | days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четверг", "П'ятниця", "Субота", "Неділя"], 8 | daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Нед"], 9 | daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Нд"], 10 | months: ["Cічень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"], 11 | monthsShort: ["Січ", "Лют", "Бер", "Квт", "Трв", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Грд"], 12 | today: "Сьогодні", 13 | weekStart: 1 14 | }; 15 | }(jQuery)); 16 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.1 4 | before_install: 5 | - time wget http://fuelux-dev.herokuapp.com/dev/node_modules.tar.gz 6 | - time tar -zxf node_modules.tar.gz 7 | - chmod +x ./node_modules 8 | install: 9 | - time ./node_modules/bower/bin/bower update 10 | env: 11 | global: 12 | - secure: |- 13 | ZK8M500JH/siU5p6jt2XRhBLV9e3N+qjicz59i6Bvkl4X4klUoGV1dMT3kb/ 14 | Li3c7lrU8Liw/dHr+a5kY5XdgCOPjOeMqZ0VRZzH0PqSyRz0Hf2AYDO5mrhX 15 | Mj/zz/CiaE82MIPlJk9Q27LheVpbCOL7q/aBakriCTJIcIxqbig= 16 | - secure: |- 17 | rrbobgc5ZJnt9NnILcJs5CNFQf/fVBGOuFDo8UqSOxNtqmpHeuLTTTqKgvdo 18 | sHZL3GDo5ujm/pPvrKv41BGi81rPPLMnQyGdmTDRgW5/F5BaKbKoOvK8opuP 19 | +M1cvJ2Cq14pEK6y2OMAooY2TY4p8MynxsqoKUGOYjmKXsLp1ZE= 20 | matrix: 21 | fast_finish: true -------------------------------------------------------------------------------- /templates/cmdb/widgets/password.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 7 | 8 |
    9 | 13 |
    14 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 15 |
    16 |
    17 | {{data|getitem:mname|getitem:"errormsg"|safe}} 18 |
    19 |
    20 |
    21 | -------------------------------------------------------------------------------- /local_settings.py: -------------------------------------------------------------------------------- 1 | LOCAL_SETTINGS = True 2 | from base.settings import * 3 | 4 | DEBUG = True 5 | TEMPLATE_DEBUG = DEBUG 6 | DATABASES.update({ 7 | 'default': { 8 | 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 9 | 'NAME': 'opencmdb', # Or path to database file if using sqlite3. 10 | 'USER': 'opencmdb', # Not used with sqlite3. 11 | 'PASSWORD': 'opencmdb', # Not used with sqlite3. 12 | 'HOST': '127.0.0.1', # Set to empty string for localhost. Not used with sqlite3. 13 | 'PORT': '3306', # Set to empty string for default. Not used with sqlite3. 14 | 'OPTIONS':{'charset': 'utf8', } 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /static/plugins/datetimepicker/js/locales/bootstrap-datetimepicker.uk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ukrainian translation for bootstrap-datetimepicker 3 | * Andrey Vityuk 4 | */ 5 | ;(function($){ 6 | $.fn.datetimepicker.dates['uk'] = { 7 | days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота", "Неділя"], 8 | daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Нед"], 9 | daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Нд"], 10 | months: ["Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"], 11 | monthsShort: ["Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру"], 12 | today: "Сьогодні", 13 | suffix: [], 14 | meridiem: [] 15 | }; 16 | }(jQuery)); -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file has been created by the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('jquery'); 3 | require('bootstrap'); 4 | 5 | require('../../js/checkbox'); 6 | require('../../js/combobox'); 7 | require('../../js/datepicker'); 8 | require('../../js/dropdown-autoflip'); 9 | require('../../js/loader'); 10 | require('../../js/placard'); 11 | require('../../js/radio'); 12 | require('../../js/search'); 13 | require('../../js/selectlist'); 14 | require('../../js/spinbox'); 15 | require('../../js/tree'); 16 | require('../../js/wizard'); 17 | require('../../js/infinite-scroll'); 18 | require('../../js/pillbox'); 19 | require('../../js/repeater'); 20 | require('../../js/repeater-list'); 21 | require('../../js/repeater-thumbnail'); 22 | require('../../js/scheduler'); -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/selectlist.html: -------------------------------------------------------------------------------- 1 |
    2 | 7 | 14 | 15 |
    -------------------------------------------------------------------------------- /templates/cmdb/widgets/textarea.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 11 |
    12 | 14 |
    15 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 16 |
    17 |
    18 | {{data|getitem:mname|getitem:"errormsg"|safe}} 19 |
    20 |
    21 |
    22 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/tree.html: -------------------------------------------------------------------------------- 1 |
      2 | 13 | 19 |
    -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/index.css: -------------------------------------------------------------------------------- 1 | .btn-panel { 2 | border: 1px solid #ddd; 3 | border-top: none; 4 | background: #f6f6f6; 5 | padding: 20px; 6 | } 7 | 8 | .thin-box { 9 | border: 1px solid #ddd; 10 | padding: 20px 20px; 11 | } 12 | 13 | #loaderWrapper .loader { 14 | float: left; 15 | margin-right: 20px; 16 | } 17 | 18 | #mainWrapper { 19 | padding-bottom: 1.5rem; 20 | } 21 | 22 | #mainWrapper section { 23 | padding-bottom: 1.5rem; 24 | } 25 | 26 | #mainWrapper section section { 27 | padding-bottom: 1.5rem; 28 | } 29 | 30 | #myInfiniteScroll1, #myInfiniteScroll2 { 31 | border: 1px solid #ddd; 32 | float: left; 33 | height: 200px; 34 | width: 45%; 35 | } 36 | 37 | #myInfiniteScroll2 { 38 | float: right; 39 | } 40 | 41 | #myPlacard1, #myPlacard2, #myPlacard3 { 42 | width: 300px; 43 | } 44 | 45 | .example-pill-class { 46 | font-style: italic; 47 | font-weight: bold; 48 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/placard-markup.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 |
    Header
    6 | 7 | 11 |
    12 | 13 |
    14 |
    15 |
    Header
    16 | 17 | 21 |
    22 | 23 |
    24 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/typeahead.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 7 |
    8 | 13 |
    14 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 15 |
    16 |
    17 | {{data|getitem:mname|getitem:"errormsg"|safe}} 18 |
    19 |
    20 |
    21 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/checkbox-no-js.less: -------------------------------------------------------------------------------- 1 | @import "forms.less"; 2 | 3 | .fuelux { 4 | .checkbox, .checkbox-inline { 5 | 6 | input[type="checkbox"]:not(.sr-only) { 7 | & ~ label { 8 | &:before { 9 | border-radius: 4px; 10 | z-index: 1; 11 | } 12 | } 13 | 14 | &:checked { 15 | & ~ label { 16 | &:before { 17 | color: white; 18 | content: "\e013"; 19 | line-height: 1em; 20 | padding-left: 1px; 21 | font-size: 8px; 22 | padding-top: 2px; 23 | } 24 | } 25 | } 26 | } 27 | 28 | &.hightlight { 29 | & + .checkbox-inline.highlight { 30 | margin-left: -14px; 31 | &.checkbox-custom { 32 | margin-left: 0px; 33 | } 34 | } 35 | } 36 | } 37 | 38 | .checkbox { 39 | 40 | &.highlight { 41 | input[type="checkbox"]:not(.sr-only) { 42 | & ~ label { 43 | left: -4px; 44 | } 45 | } 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/tree-folders-selectable.html: -------------------------------------------------------------------------------- 1 |
      2 | 13 | 19 |
    -------------------------------------------------------------------------------- /templates/cmdb/widgets/editor.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 10 | 11 |
    12 |
    13 | 15 |
    16 |
    {{data|getitem:mname|getitem:"value"}}
    17 |
    18 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 19 |
    20 |
    21 | {{data|getitem:mname|getitem:"errormsg"|safe}} 22 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/revenumerate.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 |
    3 | 6 |
    7 | 16 |
    17 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 18 |
    19 |
    20 | {{data|getitem:mname|getitem:"errormsg"|safe}} 21 |
    22 |
    23 |
    24 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/.gitignore: -------------------------------------------------------------------------------- 1 | # filesystem 2 | .DS_Store 3 | 4 | # dependencies 5 | node_modules 6 | bower_components 7 | 8 | # gh-pages 9 | _site/* 10 | 11 | # logs 12 | *.log 13 | validation-status.json 14 | 15 | # Sauce Labs. because it's classified... 16 | SAUCE_API_KEY.yml 17 | 18 | # Fuel CDN Login. because it's classified... 19 | FUEL_CDN.yml 20 | 21 | # Generated file from commonjs-test.js 22 | test/commonjs-bundle.js 23 | 24 | # Editors / IDEs 25 | .idea 26 | 27 | # node_module cache for TravisCI, etc. 28 | node_modules.tar.gz 29 | 30 | # Temp file created in the LESS build 31 | less/fuelux-no-namespace.less 32 | 33 | # sandbox 34 | dev/dev.html 35 | 36 | # screenshots 37 | page-at-timeout-* 38 | 39 | # dev css and maps 40 | dist/css/fuelux-dev.css 41 | dist/css/fuelux-dev.css.map 42 | dist/css/fuelux-fuelux-no-namespace.css.map 43 | 44 | # generate release notes 45 | notes.sh 46 | 47 | # release task and commit 48 | stage.sh 49 | 50 | # push major branch, the version tag, and SFTP upload to CDN 51 | publish.sh 52 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/input.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 10 | 11 |
    12 | 17 |
    18 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 19 |
    20 |
    21 | {{data|getitem:mname|getitem:"errormsg"|safe}} 22 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /cmdb/templatetags/cmdb_tags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #encoding:utf8 3 | from django import template 4 | import re 5 | 6 | register = template.Library() 7 | 8 | @register.simple_tag 9 | def menu_active(request, pattern): 10 | if re.search(r'^'+pattern, request.path): 11 | return 'active' 12 | return '' 13 | 14 | 15 | @register.simple_tag 16 | def get_field_name(table_field, key, attr): 17 | if not attr: 18 | attr = 'verbose_name' 19 | if table_field.get(key, ''): 20 | return table_field[key][attr] 21 | return '' 22 | 23 | 24 | @register.simple_tag 25 | def get_field_value(one_data, field, attr): 26 | if one_data.get(field, ''): 27 | return one_data[field][attr] 28 | return '' 29 | 30 | 31 | @register.filter('getitem') 32 | def getitem(item, string): 33 | try: 34 | return item.get(string, '') 35 | except : 36 | return '' 37 | 38 | 39 | @register.filter("tostring") 40 | def tostring(value): 41 | try: 42 | return str(value) 43 | except: 44 | return '' 45 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/enumerate_read_only.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 |
    3 | 6 | 7 |
    8 | 19 |
    20 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}}
    21 |
    22 |
    23 | 28 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/loader.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .loader { 4 | height: 64px; 5 | font-size: 64px; 6 | position: relative; 7 | width: 64px; 8 | 9 | &:after, &:before { 10 | #fuelux > .icon-base-styles(); 11 | 12 | bottom: 0; 13 | display: block; 14 | left: 0; 15 | position: absolute; 16 | right: 0; 17 | top: 0; 18 | } 19 | 20 | &:before { 21 | content: '\e000'; 22 | opacity: 0.33; 23 | } 24 | 25 | &.iefix:before{ 26 | color: @gray74; 27 | opacity: 1; 28 | } 29 | 30 | &[data-frame="1"]:after { 31 | content: '\e001'; 32 | } 33 | 34 | &[data-frame="2"]:after { 35 | content: '\e002'; 36 | } 37 | 38 | &[data-frame="3"]:after { 39 | content: '\e003'; 40 | } 41 | 42 | &[data-frame="4"]:after { 43 | content: '\e004'; 44 | } 45 | 46 | &[data-frame="5"]:after { 47 | content: '\e005'; 48 | } 49 | 50 | &[data-frame="6"]:after { 51 | content: '\e006'; 52 | } 53 | 54 | &[data-frame="7"]:after { 55 | content: '\e007'; 56 | } 57 | 58 | &[data-frame="8"]:after { 59 | content: '\e008'; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/selectlist.less: -------------------------------------------------------------------------------- 1 | // TODO use bs base variables if possible 2 | @selectlist-horizontal-padding: 12px; 3 | @selectlist-caret-width: 4px; 4 | 5 | .fuelux { 6 | 7 | .selectlist { 8 | 9 | &.disabled { 10 | cursor: not-allowed; 11 | } 12 | 13 | .selected-label { 14 | overflow: hidden; // helps with text flow on small screens 15 | min-width: 2em; 16 | } 17 | 18 | .dropdown-menu { 19 | min-width: inherit; 20 | overflow-y: auto; 21 | } 22 | .btn.dropdown-toggle { 23 | text-align: left; 24 | padding-right: unit((2 * @selectlist-horizontal-padding + @selectlist-caret-width), px); 25 | 26 | .caret { 27 | #fuelux > .vertical-align(); 28 | right: @selectlist-horizontal-padding; 29 | 30 | } 31 | } 32 | 33 | } 34 | 35 | .button-sizer, .selectlist-sizer{ 36 | display: inline-block; 37 | position: absolute; 38 | visibility: hidden; 39 | top: 0; 40 | float: left; 41 | .selectlist { 42 | display: block !important; 43 | } 44 | .dropdown-menu { 45 | display: block; 46 | min-width: inherit; 47 | } 48 | .selected-label { 49 | width: auto !important; 50 | } 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/fuelux.less: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | 4 | // Core variables, mixins, and icons 5 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 6 | @import "mixins.less"; 7 | @import "icons.less"; 8 | 9 | // Fuel UX controls 10 | @import "forms.less"; // forms.less contains code shared between form elements. 11 | @import "checkbox.less"; // Checkbox styles that will be deprecated. 12 | @import "checkbox-no-js.less"; // Checkbox styles that are not dependant upon custom javascript controls. 13 | @import "radio.less"; // Radio styles that will be deprecated. 14 | @import "radio-no-js.less"; // Radio styles that are not dependant upon custom javascript controls. 15 | @import "combobox.less"; 16 | @import "datepicker.less"; 17 | @import "infinite-scroll.less"; 18 | @import "intelligent-dropdown.less"; 19 | @import "loader.less"; 20 | @import "pillbox.less"; 21 | @import "placard.less"; 22 | @import "repeater.less"; 23 | @import "repeater-list.less"; 24 | @import "repeater-thumbnail.less"; 25 | @import "spinbox.less"; 26 | @import "scheduler.less"; 27 | @import "search.less"; 28 | @import "selectlist.less"; 29 | @import "tree.less"; 30 | @import "wizard.less"; 31 | @import "utility.less"; 32 | 33 | 34 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/grunt/commonjs-reference-module.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grunt task for the CommonJS module generation 3 | * http://getbootstrap.com 4 | * Copyright 2014-2015 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var fs = require('fs'); 11 | var path = require('path'); 12 | 13 | var banner = '// This file has been created by the `commonjs` Grunt task.' + 14 | ' You can require() this file in a CommonJS environment.\n' + 15 | 'require(\'jquery\');\n' + 16 | 'require(\'bootstrap\');\n\n'; 17 | 'require(\'moment\');\n\n'; 18 | 19 | module.exports = function createBundledReferenceModule(grunt, files, destFile) { 20 | var destDir = path.dirname(destFile); 21 | 22 | function srcPathToDestRequire(files) { 23 | var requirePath = path.relative(destDir, files).replace(/\\/g, '/').replace(/\.js$/g, ''); 24 | return 'require(\'' + requirePath + '\');'; 25 | } 26 | 27 | var moduleOutputJs = banner + files.map(srcPathToDestRequire).join('\n'); 28 | try { 29 | fs.writeFileSync(destFile, moduleOutputJs); 30 | } catch (err) { 31 | grunt.fail.warn(err); 32 | } 33 | grunt.log.writeln('CommonJS Bundled Reference file created: ' + destFile.cyan); 34 | }; -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/.bithoundrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | "**/deps/**", 4 | "**/node_modules/**", 5 | "**/thirdparty/**", 6 | "**/vendor/**", 7 | "**/**-min-**", 8 | "**/**-min.**", 9 | "**/**.min.**", 10 | "**/**jquery.?(ui|effects)-*.*.?(*).?(cs|j)s", 11 | "**/**jquery-*.*.?(*).?(cs|j)s", 12 | "**/prototype?(*).js", 13 | "**/**?(*).ts", 14 | "**/mootools*.*.*.js", 15 | "**/dojo.js", 16 | "**/MochiKit.js", 17 | "**/yahoo-*.js", 18 | "**/yui*.js", 19 | "**/ckeditor*.js", 20 | "**/tiny_mce*.js", 21 | "**/tiny_mce/?(langs|plugins|themes|utils)/**", 22 | "**/MathJax/**", 23 | "**/shBrush*.js", 24 | "**/shCore.js", 25 | "**/shLegacy.js", 26 | "**/modernizr.custom.?(*).js", 27 | "**/knockout-*.*.*.debug.js", 28 | "**/extjs/*.js", 29 | "**/extjs/*.xml", 30 | "**/extjs/*.txt", 31 | "**/extjs/*.html", 32 | "**/extjs/*.properties", 33 | "**/extjs/.sencha", 34 | "**/extjs/docs/**", 35 | "**/extjs/builds/**", 36 | "**/extjs/cmd/**", 37 | "**/extjs/examples/**", 38 | "**/extjs/locale/**", 39 | "**/extjs/packages/**", 40 | "**/extjs/plugins/**", 41 | "**/extjs/resources/**", 42 | "**/extjs/src/**", 43 | "**/extjs/welcome/**", 44 | "bower_components/**", 45 | "**/dist/**" 46 | ] 47 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuelux", 3 | "description": "Extending Bootstrap with additional lightweight JavaScript controls.", 4 | "keywords": [ 5 | "application", 6 | "bootstrap", 7 | "controls", 8 | "css", 9 | "exacttarget", 10 | "front-end", 11 | "fuelux", 12 | "fuel ux", 13 | "js", 14 | "salesforce", 15 | "user interface", 16 | "web" 17 | ], 18 | "homepage": "http://getfuelux.com", 19 | "dependencies": { 20 | "jquery": "latest", 21 | "requirejs": "2.x", 22 | "bootstrap": "3.x", 23 | "moment": "2.x" 24 | }, 25 | "devDependencies": { 26 | "jquery": null, 27 | "jquery-1.9.1": "jquery#1.9.1", 28 | "qunit": "~1.14.0", 29 | "requirejs-text": "2.x", 30 | "underscore": "1.x", 31 | "blanket": "1.x" 32 | }, 33 | "ignore": [ 34 | "**/.*", 35 | "_*", 36 | "*.yml", 37 | "BACKLOG.md", 38 | "data.js", 39 | "dev", 40 | "devserver.js", 41 | "dist/fuelux.zip", 42 | "Gruntfile.js", 43 | "index.css", 44 | "index.html", 45 | "index.js", 46 | "node_modules", 47 | "Procfile", 48 | "test" 49 | ], 50 | "license": "BSD-3-Clause", 51 | "main": [ 52 | "dist/css/fuelux.css", 53 | "dist/js/fuelux.js", 54 | "dist/fonts/fuelux.eot", 55 | "dist/fonts/fuelux.svg", 56 | "dist/fonts/fuelux.ttf", 57 | "dist/fonts/fuelux.woff" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/js/all.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX All 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2014 ExactTarget 6 | * Licensed under the BSD New license. 7 | * 8 | * NOTE: This file works with AMD only. 9 | */ 10 | 11 | (function (factory) { 12 | if (typeof define === 'function' && define.amd) { 13 | // if AMD loader is available, register as an anonymous module. 14 | define(factory); 15 | } else { 16 | // OR print to the console that this file is AMD only, if possible 17 | if(window && window.console && window.console.log){ 18 | window.console.log('WARNING: The all.js file in the Fuel UX src directory is for use with AMD only.'); 19 | } 20 | } 21 | }(function (require) { 22 | 23 | require('jquery'); 24 | require('bootstrap'); 25 | 26 | require('fuelux/checkbox'); 27 | require('fuelux/combobox'); 28 | require('fuelux/datepicker'); 29 | require('fuelux/dropdown-autoflip'); 30 | require('fuelux/infinite-scroll'); 31 | require('fuelux/loader'); 32 | require('fuelux/pillbox'); 33 | require('fuelux/placard'); 34 | require('fuelux/radio'); 35 | require('fuelux/repeater'); 36 | require('fuelux/repeater-list'); 37 | require('fuelux/repeater-thumbnail'); 38 | require('fuelux/scheduler'); 39 | require('fuelux/search'); 40 | require('fuelux/spinbox'); 41 | require('fuelux/selectlist'); 42 | require('fuelux/tree'); 43 | require('fuelux/wizard'); 44 | 45 | })); 46 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/tests-no-moment.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | define(function(require){ 6 | var $ = require('jquery'); 7 | 8 | QUnit.start(); // starting qunit, or phantom js will have a problem 9 | 10 | // Needed for saucelab testing 11 | var log = []; 12 | var testName; 13 | 14 | QUnit.done(function (test_results) { 15 | var tests = []; 16 | for(var i = 0, len = log.length; i < len; i++) { 17 | var details = log[i]; 18 | tests.push({ 19 | name: details.name, 20 | result: details.result, 21 | expected: details.expected, 22 | actual: details.actual, 23 | source: details.source 24 | }); 25 | } 26 | test_results.tests = tests; 27 | 28 | window.global_test_results = test_results; 29 | 30 | // hide passed tests, helps with VM testing screencasts 31 | if (!$('#qunit-filter-pass').is(':checked')) { 32 | $('#qunit-filter-pass').click(); 33 | } 34 | 35 | }); 36 | QUnit.testStart(function(testDetails){ 37 | QUnit.log = function(details){ 38 | if (!details.result) { 39 | details.name = testDetails.name; 40 | log.push(details); 41 | } 42 | }; 43 | }); 44 | 45 | require('test/datepicker-test'); 46 | 47 | }); 48 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/spinbox.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .spinbox { 4 | display: inline-block; 5 | position: relative; 6 | 7 | &.digits-3 { 8 | width: 60px; 9 | } 10 | 11 | &.disabled { 12 | .spinbox-buttons { 13 | cursor: not-allowed; 14 | } 15 | } 16 | 17 | .spinbox-input { 18 | float: left; 19 | padding-bottom: 3px; /* Magic number */ 20 | padding: 0px 25px 0px 7px; 21 | 22 | &::-ms-clear { 23 | display:none; 24 | } 25 | } 26 | 27 | .btn { 28 | position: relative; 29 | width: 20px; 30 | height: 13px; 31 | padding-top: 0; 32 | padding-right: 9px; 33 | padding-left: 9px; 34 | 35 | &.disabled { 36 | cursor: not-allowed; 37 | } 38 | } 39 | 40 | .spinbox-buttons { 41 | position: absolute; 42 | height: 28px; 43 | width: 20px; 44 | right: 2px; 45 | } 46 | 47 | .spinbox-up { 48 | padding: 0 0 14px 1px; 49 | top: 2px; 50 | 51 | .glyphicon-chevron-up { 52 | position:relative; 53 | top: 0px; 54 | } 55 | } 56 | 57 | // fix radius from BS btn-group 58 | .btn-group > .btn.spinbox-up { 59 | border-top-right-radius: 4px; 60 | } 61 | 62 | .spinbox-down { 63 | padding: 0 0 8px 1px; 64 | top: 2px; 65 | height: 15px; 66 | border-bottom-left-radius: 4px; 67 | 68 | .glyphicon-chevron-down { 69 | position: relative; 70 | left: -1px; 71 | top: 0px; 72 | } 73 | } 74 | input { 75 | &::-ms-clear { 76 | display:none; 77 | } 78 | } 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /templates/cmdb/widgets/enumerate.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 10 | 11 |
    12 | 13 | 25 | 26 |
    27 | {{ data|getitem:mname|getitem:"help_text"|safe|capfirst }} 28 |
    29 |
    30 | {{ data|getitem:mname|getitem:"errormsg"|safe }} 31 |
    32 |
    33 |
    34 | 41 | -------------------------------------------------------------------------------- /templates/base/base.html: -------------------------------------------------------------------------------- 1 | {% extends "base/base_bootstrap.html" %} 2 | 3 | {% load cmdb_tags %} 4 | 5 | {% block title %} 6 | {% endblock %} 7 | 8 | {% block body %} 9 | 33 |
    34 |
    35 |
    36 |
    37 | {% block content %} 38 | {% endblock %} 39 |
    40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/checkbox-markup.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 8 |
    9 | 10 |
    11 | 15 |
    16 | 17 |
    18 | 22 |
    23 | 24 |
    25 | 29 |
    30 | 31 | 32 |
    33 |
    34 | 38 |
    39 | 40 |
    41 | 42 |
    -------------------------------------------------------------------------------- /templates/cmdb/widgets/multiselect2.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 10 | 11 |
    12 | 13 | 25 | 26 | 28 | ( 可多选) 29 | 30 |
    31 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 32 |
    33 |
    34 | {{data|getitem:mname|getitem:"errormsg"|safe}} 35 |
    36 |
    37 |
    38 | 44 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/datetime.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
    4 | 11 | 12 |
    13 |
    14 | 26 | 27 | 28 | 29 |
    30 |
    31 | {{ data|getitem:mname|getitem:"help_text"|safe|capfirst}} 32 |
    33 |
    34 | {{data|getitem:mname|getitem:"errormsg"|safe}} 35 |
    36 |
    37 |
    38 | 39 | 48 | -------------------------------------------------------------------------------- /myproject/urls.py: -------------------------------------------------------------------------------- 1 | # encoding:utf8 2 | from django.conf.urls import patterns, include, url 3 | from django.contrib import admin 4 | from django.http import HttpResponseRedirect 5 | import myproject.api 6 | 7 | urlpatterns = patterns('', 8 | url(r'^$', lambda x: HttpResponseRedirect('/login/')), 9 | url(r'^logout/$', 'cmdb.views.logout_view', name='cmdb_logout'), 10 | url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, 11 | name='cmdb_login'), 12 | url(r'^home/$', 'cmdb.views.home', name='home'), 13 | 14 | # 主机管理 15 | url(r'cmdb/(?P\w+)/show/$', 'cmdb.views.show_all'), 16 | url(r'cmdb/(?P\w+)/delete/(?P\d+)/$', 'cmdb.views.delete'), 17 | url(r'cmdb/(?P\w+)/add/(?P\d+)/$', 'cmdb.views.add_modify'), 18 | url(r'cmdb/(?P\w+)/modify/(?P\d+)/$', 'cmdb.views.add_modify'), 19 | url(r'cmdb/(?P\w+)/import/$', 'cmdb.views.import_data'), 20 | 21 | # 操作历史 22 | url(r'^cmdb/changelog/', include('echelon.urls')), 23 | ) 24 | 25 | # Wire up our API using automatic URL routing. 26 | # Additionally, we include login URLs for the browsable API. 27 | 28 | urlpatterns += patterns( 29 | '', 30 | url(r'^api/', include(myproject.api.router.urls)), 31 | url(r'^api-auth/', include('rest_framework.urls', 32 | namespace='rest_framework')), 33 | ) 34 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/sauce_browsers.yml: -------------------------------------------------------------------------------- 1 | [ 2 | # Docs: https://saucelabs.com/docs/platforms/webdriver 3 | 4 | { 5 | browserName: "safari", 6 | platform: "OS X 10.9" 7 | }, 8 | { 9 | browserName: "chrome", 10 | platform: "OS X 10.9" 11 | }, 12 | { 13 | browserName: "firefox", 14 | platform: "OS X 10.9" 15 | }, 16 | 17 | # Mac Opera not currently supported by Sauce Labs 18 | 19 | { 20 | browserName: "internet explorer", 21 | version: "11", 22 | platform: "Windows 8.1" 23 | }, 24 | { 25 | browserName: "internet explorer", 26 | version: "10", 27 | platform: "Windows 8" 28 | }, 29 | { 30 | browserName: "internet explorer", 31 | version: "9", 32 | platform: "Windows 7" 33 | }, 34 | 35 | # Not Supported by MC 36 | # { 37 | # browserName: "internet explorer", 38 | # version: "8", 39 | # platform: "Windows 7" 40 | # }, 41 | 42 | { 43 | browserName: "chrome", 44 | platform: "Windows 8.1" 45 | }, 46 | { 47 | browserName: "firefox", 48 | platform: "Windows 8.1" 49 | }, 50 | 51 | # Win Opera 15+ not currently supported by Sauce Labs 52 | 53 | { 54 | browserName: "iphone", 55 | platform: "OS X 10.9", 56 | version: "7.1" 57 | }, 58 | 59 | # iOS Chrome not currently supported by Sauce Labs 60 | 61 | # Linux (unofficial) 62 | { 63 | browserName: "chrome", 64 | platform: "Linux" 65 | }, 66 | { 67 | browserName: "firefox", 68 | platform: "Linux" 69 | } 70 | 71 | # Android Chrome not currently supported by Sauce Labs 72 | 73 | # { # Android Browser (super-unofficial) 74 | # browserName: "android", 75 | # version: "4.0", 76 | # platform: "Linux" 77 | # } 78 | ] 79 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/pillbox-with-pills.html: -------------------------------------------------------------------------------- 1 |
    2 |
      3 | 4 |
    • 5 | Item 1 6 | 7 | Remove 8 | 9 |
    • 10 |
    • 11 | Item 2 12 | 13 | Remove 14 | 15 |
    • 16 |
    • 17 | Item 3 18 | 19 | Remove 20 | 21 |
    • 22 |
    • 23 | Item 4 24 | 25 | Remove 26 | 27 |
    • 28 |
    • 29 | Item 5 30 | 31 | Remove 32 | 33 |
    • 34 | 35 |
    • 36 | and more... 37 | 38 | 42 | 43 |
    • 44 |
    45 |
    -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 ExactTarget, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 5 | following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following 8 | disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 11 | following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote 14 | products derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | ==================================================================== 25 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/repeater-thumbnail.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .repeater-thumbnail { 4 | border: 1px solid @gray87; 5 | color: @gray40; 6 | float: left; 7 | font-size: 14px; 8 | min-height: 110px; 9 | min-width: 100px; 10 | margin: 8px 7px; 11 | text-align: center; 12 | 13 | img { 14 | display: block; 15 | margin-top: 10px; 16 | margin-bottom: 3px; 17 | } 18 | 19 | &-cont { 20 | height: 100%; 21 | overflow-y: auto; 22 | padding: 6px; 23 | width: 100%; 24 | 25 | &.align-center, &.align-justify, &.align-left, &.align-right { 26 | position: relative; 27 | font-size: 0.1px; 28 | 29 | &:after { 30 | display: inline-block; 31 | width: 100%; 32 | content: ''; 33 | } 34 | 35 | .infinitescroll { 36 | &-end, &-load { 37 | display: inline-block; 38 | width: 100%; 39 | } 40 | } 41 | 42 | .repeater-thumbnail { 43 | display: inline-block; 44 | float: none; 45 | font-size: 14px; 46 | 47 | &:after { 48 | content: ' '; 49 | } 50 | } 51 | } 52 | &.align-center { text-align: center; } 53 | &.align-justify { text-align: justify; } 54 | &.align-left { text-align: left; } 55 | &.align-right { text-align: right; } 56 | 57 | div.empty { 58 | font-size: 14px; 59 | font-style: italic; 60 | padding: 14px 10px 20px; 61 | text-align: center; 62 | } 63 | 64 | .selectable { 65 | &:hover { 66 | background: @selectableHover; 67 | cursor: pointer; 68 | } 69 | 70 | &.selected { 71 | background: @selected; 72 | 73 | &:hover { 74 | background: @selectedHover; 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/fuelux.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/sauce_browsers_tricky.yml: -------------------------------------------------------------------------------- 1 | [ 2 | # Docs: https://saucelabs.com/docs/platforms/webdriver 3 | 4 | # { 5 | # browserName: "internet explorer", 6 | # version: "8", 7 | # platform: "Windows XP" 8 | # }, 9 | 10 | # { 11 | # browserName: "googlechrome", 12 | # version: "31", 13 | # platform: "Windows 7" 14 | # }, 15 | 16 | { 17 | browserName: "internet explorer", 18 | version: "9", 19 | platform: "Windows 7" 20 | }, 21 | 22 | # Linux (unofficial) 23 | # { 24 | # browserName: "googlechrome", 25 | # platform: "Linux", 26 | # version: "31" 27 | # }, 28 | { 29 | browserName: "firefox", 30 | platform: "Linux" 31 | }, 32 | 33 | #{ 34 | # browserName: "firefox", 35 | # version: "28", 36 | # platform: "Windows 7" 37 | #}, 38 | 39 | { 40 | browserName: "internet explorer", 41 | version: "10", 42 | platform: "Windows 8" 43 | }, 44 | 45 | { 46 | browserName: "internet explorer", 47 | version: "11", 48 | platform: "Windows 8.1" 49 | }, 50 | 51 | # { 52 | # browserName: "safari", 53 | # version: "6", 54 | # platform: "OS X 10.8" 55 | # }, 56 | 57 | { 58 | browserName: "iphone", 59 | version: "7", 60 | platform: "OS X 10.9" 61 | }, 62 | 63 | { 64 | browserName: "internet explorer", 65 | version: "8", 66 | platform: "Windows 7" 67 | } 68 | 69 | # # this was probably what it was built on, no? 70 | # # { 71 | # # browserName: "googlechrome", 72 | # # platform: "OS X 10.9", 73 | # # }, 74 | 75 | # Mac Opera not currently supported by Sauce Labs 76 | 77 | # { # Unofficial 78 | # browserName: "internet explorer", 79 | # version: "7", 80 | # platform: "Windows XP" 81 | # }, 82 | 83 | # { 84 | # browserName: "firefox", 85 | # platform: "OS X 10.9", 86 | # version: "28" 87 | # }, 88 | ] -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dist/fonts/fuelux.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /cmdb/model_form.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding:utf8 3 | 4 | from django.forms import ModelForm 5 | from models import * 6 | from django.contrib.auth.models import User, Permission, Group 7 | from django.contrib.auth.hashers import make_password 8 | 9 | 10 | class Server_Group_CheckForm(ModelForm): 11 | class Meta: 12 | model = Server_Group 13 | fields = '__all__' 14 | 15 | 16 | class IDC_CheckForm(ModelForm): 17 | class Meta: 18 | model = IDC 19 | fields = '__all__' 20 | 21 | 22 | class Project_CheckForm(ModelForm): 23 | class Meta: 24 | model = Project 25 | fields = '__all__' 26 | 27 | 28 | class Server_Role_CheckForm(ModelForm): 29 | class Meta: 30 | model = Server_Role 31 | fields = '__all__' 32 | 33 | 34 | class Server_Device_CheckForm(ModelForm): 35 | class Meta: 36 | model = Server_Device 37 | fields = '__all__' 38 | 39 | 40 | 41 | class User_CheckFrom(ModelForm): 42 | class Meta: 43 | model = User 44 | fields = ['username', 45 | 'password', 46 | 'email', 47 | 'is_superuser', 48 | 'is_active', 49 | 'is_staff', 50 | 'user_permissions'] 51 | 52 | def save(self): 53 | # 如果密码不是以pbkdf加密字符串开头的, 表示用户输入了自己的密码, 需要重新加密 54 | if not self.instance.password.startswith("pbkdf2_sha256$"): 55 | print self.instance.password 56 | self.instance.password = make_password(self.instance.password) 57 | super(User_CheckFrom, self).save() 58 | 59 | class Group_CheckFrom(ModelForm): 60 | class Meta: 61 | model = Group 62 | fields = '__all__' 63 | 64 | class Permission_CheckFrom(ModelForm): 65 | class Meta: 66 | model = Permission 67 | fields = '__all__' 68 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/radio-markup.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 8 |
    9 | 10 |
    11 | 15 | 19 | 23 |
    24 | 25 |
    26 | 30 |
    31 | 32 |
    33 | 37 |
    38 | 39 |
    40 | 44 |
    45 | 46 | 47 |
    48 |
    49 | 53 |
    54 | 55 |
    56 | 57 |
    58 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/browser-globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FuelUX Component Initialization (via Browser Globals) 6 | 7 | 8 | 9 |

    Fuel UX Global Variable Test Suite

    10 | 11 |

    12 | 13 |
    14 |

    15 |
      16 |
      17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /templates/rest_framework/api.html: -------------------------------------------------------------------------------- 1 | {% extends "rest_framework/base.html" %} 2 | 3 | {% block head %} 4 | {% if not request.user.is_authenticated and not user.is_authenticated %} 5 | 8 | {% endif %} 9 | 10 | {{ block.super }} 11 | {% endblock %} 12 | 13 | {% load cmdb_tags %} 14 | 15 | {% block title %}CMDB SYSTEM{% endblock %} 16 | 17 | {% block style %} 18 | 19 | {{ block.super }} 20 | 31 | 32 | {% endblock %} 33 | 34 | {% block navbar %} 35 | 59 | {% endblock %} -------------------------------------------------------------------------------- /templates/base/base_bootstrap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CMDB SYSTEM 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% block css %} 19 | {% endblock %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | {% block js %} 34 | {% endblock %} 35 | 36 | 37 | {% block body %} 38 | {% endblock %} 39 | 40 | 41 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | define(function(require){ 6 | var $ = require('jquery'); 7 | 8 | QUnit.start(); // starting qunit, or phantom js will have a problem 9 | 10 | // Needed for saucelab testing 11 | var log = []; 12 | var testName; 13 | 14 | QUnit.done(function (test_results) { 15 | var tests = []; 16 | for(var i = 0, len = log.length; i < len; i++) { 17 | var details = log[i]; 18 | tests.push({ 19 | name: details.name, 20 | result: details.result, 21 | expected: details.expected, 22 | actual: details.actual, 23 | source: details.source 24 | }); 25 | } 26 | test_results.tests = tests; 27 | 28 | window.global_test_results = test_results; 29 | 30 | // hide passed tests, helps with VM testing screencasts 31 | if (!$('#qunit-filter-pass').is(':checked')) { 32 | $('#qunit-filter-pass').click(); 33 | } 34 | 35 | }); 36 | QUnit.testStart(function(testDetails){ 37 | QUnit.log = function(details){ 38 | if (!details.result) { 39 | details.name = testDetails.name; 40 | log.push(details); 41 | } 42 | }; 43 | }); 44 | 45 | require('moment'); 46 | require('./test/checkbox-test'); 47 | require('./test/combobox-test'); 48 | require('./test/datepicker-moment-test'); 49 | require('./test/infinite-scroll-test'); 50 | require('./test/loader-test'); 51 | require('./test/pillbox-test'); 52 | require('./test/placard-test'); 53 | require('./test/radio-test'); 54 | require('./test/repeater-test'); 55 | require('./test/repeater-list-test'); 56 | require('./test/repeater-thumbnail-test'); 57 | require('./test/scheduler-test'); 58 | require('./test/search-test'); 59 | require('./test/selectlist-test'); 60 | require('./test/spinbox-test'); 61 | require('./test/tree-test'); 62 | require('./test/wizard-test'); 63 | 64 | }); 65 | -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base/base_bootstrap.html" %} 2 | {% block body %} 3 | 38 | 39 | {% endblock %} -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/fonts/src/loader_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/dev/dev.html.example: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | dev.html 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /templates/cmdb/widgets/file.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | 3 |
      4 | 10 | 11 |
      12 |
      13 | 17 |
      18 |
      19 |
      20 | {{data|getitem:mname|getitem:"help_text"|safe|capfirst}} 21 | {% if data|getitem:mname|getitem:"value" %} 22 | 已上传: {{data|getitem:mname|getitem:"value"}} 23 |
      24 | MD5: {{data|getitem:"md5sum"|getitem:"value"}} 25 | {% endif %} 26 |
      27 |
      28 |
      29 |
      33 |
      34 |
      35 |
      36 | 37 | 剩余时间: 0 秒 38 | 39 | 40 | 41 | 42 | 速度: 0 KBps 43 | 44 | 45 | 46 | 47 | 大小: 0 B 48 | 49 | 50 |
      51 |
      52 | {{data|getitem:mname|getitem:"errormsg"|safe}} 53 |
      54 |
      55 |
      56 | 57 | 60 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/radio-no-js.less: -------------------------------------------------------------------------------- 1 | @import "forms.less"; 2 | 3 | .fuelux { 4 | .radio, .radio-inline { 5 | 6 | input[type="radio"]:not(.sr-only) { 7 | 8 | & ~ label { 9 | &:before { 10 | border-radius: 8px; 11 | z-index: 1; 12 | } 13 | } 14 | 15 | &:checked { 16 | 17 | & ~ label { 18 | &:before { 19 | background: @checkboxPrimaryColor; /* Old browsers */ 20 | background: -moz-radial-gradient(center, ellipse cover, @true-white 0%, @true-white 40%, @checkboxPrimaryColor 41%, @checkboxPrimaryColor 100%); /* FF3.6+ */ 21 | background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,@true-white), color-stop(40%,@true-white), color-stop(41%,@checkboxPrimaryColor), color-stop(100%,@checkboxPrimaryColor)); /* Chrome,Safari4+ */ 22 | background: -webkit-radial-gradient(center, ellipse cover, @true-white 0%, @true-white 40%, @checkboxPrimaryColor 41%, @checkboxPrimaryColor 100%); /* Chrome10+,Safari5.1+ */ 23 | background: -o-radial-gradient(center, ellipse cover, @true-white 0%, @true-white 40%, @checkboxPrimaryColor 41%, @checkboxPrimaryColor 100%); /* Opera 12+ */ 24 | background: -ms-radial-gradient(center, ellipse cover, @true-white 0%, @true-white 40%, @checkboxPrimaryColor 41%, @checkboxPrimaryColor 100%); /* IE10+ */ 25 | background: radial-gradient(ellipse at center, @true-white 0%, @true-white 40%, @checkboxPrimaryColor 41%, @checkboxPrimaryColor 100%); /* W3C */ 26 | filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr='@{true-white}', endColorstr='@{checkboxPrimaryColor}', GradientType=1)"; /* IE6-9 fallback on horizontal gradient */ 27 | } 28 | } 29 | } 30 | 31 | 32 | /* for keyboard tabbing */ 33 | &:hover ~ label, &:active ~ label, &:focus ~ label { 34 | 35 | &:before { 36 | .checkbox-radio-focus(); 37 | } 38 | 39 | } 40 | /* for keyboard tabbing */ 41 | &:active:hover ~ label, &:focus:hover ~ label, &:focus:hover ~ label, &:checked:hover ~ label { 42 | &:before { 43 | outline-color: none; 44 | outline-offset: 0; 45 | outline-style: none; 46 | outline-width: 0; 47 | cursor: default; 48 | } 49 | 50 | &, &:hover { 51 | color: @text-color; 52 | cursor: default; 53 | } 54 | } 55 | 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/pillbox-markup.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 |
        5 |
      • 6 | Item 1 7 | 8 | Remove 9 | 10 |
      • 11 |
      • 12 | Item 2 13 | 14 | Remove 15 | 16 |
      • 17 |
      • 18 | Item 3 19 | 20 | Remove 21 | 22 |
      • 23 |
      • 24 | Item 4 25 | 26 | Remove 27 | 28 |
      • 29 |
      • 30 | Item 5 31 | 32 | Remove 33 | 34 |
      • 35 |
      • 36 | and more... 37 | 38 | 39 | 43 | 44 |
      • 45 |
      46 |
      47 | 48 |
      Empty Pillbox
      49 | 50 |
      51 |
        52 |
      • 53 | and more... 54 | 55 | 56 | 60 | 61 |
      • 62 |
      63 |
      64 | 65 |
      66 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/repeater.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .repeater { 4 | border: 1px solid @gray87; 5 | border-radius: 4px; 6 | 7 | &-canvas { 8 | &.scrolling{ 9 | bottom: 0; 10 | left: 0; 11 | overflow-y: auto; 12 | position: absolute; 13 | right: 0; 14 | top: 0; 15 | } 16 | } 17 | 18 | &-header, 19 | &-footer 20 | { 21 | background: @gray98; 22 | min-height: 50px; 23 | padding: 8px; 24 | .clearfix; 25 | 26 | &-left { 27 | float: left; 28 | } 29 | 30 | &-right { 31 | float: right; 32 | } 33 | 34 | @media (max-width: 625px) { 35 | &-left, 36 | &-right { 37 | float: none; 38 | .clearfix; 39 | } 40 | 41 | &-left { 42 | margin-bottom: 8px; 43 | } 44 | } 45 | } 46 | 47 | &-header { 48 | border-bottom: 1px solid @gray87; 49 | #fuelux > .border-top-radius(4px); 50 | } 51 | 52 | &-footer { 53 | border-top: 1px solid @gray87; 54 | #fuelux > .border-bottom-radius(4px); 55 | } 56 | 57 | &-loader { 58 | display: none; 59 | left: 50%; 60 | position: absolute; 61 | margin: -32px 0 0 -32px; 62 | top: 50%; 63 | } 64 | 65 | &-viewport { 66 | min-height: 80px; 67 | position: relative; 68 | } 69 | 70 | &-pagination { 71 | 72 | label { 73 | font-weight: normal; 74 | } 75 | 76 | .repeater-primaryPaging { 77 | display: none; 78 | vertical-align: middle; 79 | width: 116px; 80 | 81 | &.active { 82 | display: inline-block; 83 | } 84 | 85 | ul.dropdown-menu { 86 | min-width: 116px; 87 | } 88 | } 89 | 90 | .repeater-secondaryPaging { 91 | display: none; 92 | width: 82px; 93 | 94 | &.active { 95 | display: inline-block; 96 | } 97 | } 98 | } 99 | 100 | &-search { 101 | float: left; 102 | width: 200px; 103 | } 104 | 105 | &-title { 106 | display: block; 107 | float: left; 108 | line-height: 34px; 109 | margin-right: 10px; 110 | } 111 | 112 | /* 113 | * reinforce spacing around control buttons 114 | */ 115 | &-itemization .selectlist, // TODO add specfic class for page size dropdown 116 | &-filters, 117 | &-secondaryPaging, 118 | &-primaryPaging, 119 | &-next, 120 | &-prev 121 | { 122 | margin: auto 0.3em; 123 | } 124 | } 125 | 126 | } -------------------------------------------------------------------------------- /templates/add_modify.html: -------------------------------------------------------------------------------- 1 | {% load cmdb_tags %} 2 | {% block content %} 3 |
      4 |
      5 | 6 | {{ tag_name }} 7 | 8 |
      9 | 10 |
      11 |
      14 | {% csrf_token %} 15 |
      16 | {% for field_name in list_display %} 17 | {% with field_info=data|getitem:field_name %} 18 | {% with widget="cmdb/widgets/"|add:field_info.field_widget|add:".html" mtclass="col-md-2 col-lg-2" mdclass="col-md-10 col-lg-10" %} 19 | {% include widget with mname=field_name %} 20 | {% endwith %} 21 | {% endwith %} 22 | {% endfor %} 23 |
      24 |
      25 |
      26 | {{ tag_name }} 27 | 取消 28 |
      29 |
      30 |
      31 |
      32 |
      33 | 34 | 62 | 63 | {% endblock %} 64 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/spinbox-markup.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 | 6 |
      7 | 8 | 9 |
      10 | 13 | 16 |
      17 |
      18 | 19 |
      20 | 21 |
      22 | 23 | 24 |
      25 | 26 | 27 |
      28 | 31 | 34 |
      35 |
      36 | 37 |
      38 | 39 |
      40 | 41 |
      42 | 43 |
      44 | 45 | 46 |
      47 | 50 | 53 |
      54 |
      55 | 56 |
      57 |
      58 | 59 | 60 |
      -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/commonjs-test.js: -------------------------------------------------------------------------------- 1 | window.$ = window.jQuery = require('jquery'); 2 | var bootstrap = require('bootstrap'); 3 | var moment = require('moment'); 4 | var fuelux = require('../dist/js/npm'); 5 | var QUnit = require('qunitjs'); 6 | 7 | // In order to be be UMD compliant, modules must work with 8 | // CommonJS. The following tests check to see if the plugin 9 | // is on the jQuery namespace and nothing else. 10 | 11 | test('combobox should be defined on jQuery object', function () { 12 | ok($().combobox, 'combobox method is defined'); 13 | }); 14 | 15 | test('datepicker should be defined on the jQuery object', function () { 16 | ok($().datepicker, 'datepicker method is defined'); 17 | }); 18 | 19 | test('dropdownautoflip should be defined on the jQuery object', function () { 20 | ok($().dropdownautoflip, 'dropdownautoflip method is defined'); 21 | }); 22 | 23 | test('infinitescroll should be defined on the jQuery object', function () { 24 | ok($().infinitescroll, 'infinitescroll method is defined'); 25 | }); 26 | 27 | test('loader should be defined on the jQuery object', function () { 28 | ok($().loader, 'loader method is defined'); 29 | }); 30 | 31 | test('pillbox should be defined on jQuery object', function () { 32 | ok($().pillbox, 'pillbox method is defined'); 33 | }); 34 | 35 | test('radio should be defined on jQuery object', function () { 36 | ok($().radio, 'radio method is defined'); 37 | }); 38 | 39 | test('repeater should be defined on jQuery object', function () { 40 | ok($().repeater, 'repeater method is defined'); 41 | }); 42 | 43 | test('repeater list should be defined on jQuery object', function () { 44 | ok($.fn.repeater.viewTypes.list, 'repeater list view is defined'); 45 | }); 46 | 47 | test('repeater thumbnail should be defined on jQuery object', function () { 48 | ok($.fn.repeater.viewTypes.thumbnail, 'repeater thumbnail view is defined'); 49 | }); 50 | 51 | test('scheduler should be defined on the jQuery object', function () { 52 | ok($().scheduler, 'scheduler method is defined'); 53 | }); 54 | 55 | test('search should be defined on jQuery object', function () { 56 | ok($().search, 'search method is defined'); 57 | }); 58 | 59 | test('selectlist should be defined on jQuery object', function () { 60 | ok($().selectlist, 'selectlist method is defined'); 61 | }); 62 | 63 | test('spinbox should be defined on jQuery object', function () { 64 | ok($().spinbox, 'spinbox method is defined'); 65 | }); 66 | 67 | test('tree should be defined on jQuery object', function () { 68 | ok($().tree, 'tree method is defined'); 69 | }); 70 | 71 | test('wizard should be defined on jQuery object', function () { 72 | ok($().wizard, 'wizard method is defined'); 73 | }); 74 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "email": "kparkerson@exacttarget.com", 4 | "name": "ExactTarget", 5 | "url": "http://code.exacttarget.com" 6 | }, 7 | "bugs": { 8 | "url": "https://github.com/ExactTarget/fuelux/issues" 9 | }, 10 | "dependencies": { 11 | "bootstrap": "3.x", 12 | "jquery": "2.x", 13 | "moment": "2.x" 14 | }, 15 | "description": "Base Fuel UX styles and controls", 16 | "devDependencies": { 17 | "bower": "1.x", 18 | "connect": "3.x", 19 | "grunt": "0.x", 20 | "grunt-banner": "0.x", 21 | "grunt-blanket-qunit": "~0.2.0", 22 | "grunt-browserify": "3.x", 23 | "grunt-bump": "0.x", 24 | "grunt-cli": "0.x", 25 | "grunt-contrib-clean": "0.x", 26 | "grunt-contrib-compress": "0.x", 27 | "grunt-contrib-concat": "0.x", 28 | "grunt-contrib-connect": "0.x", 29 | "grunt-contrib-copy": "0.x", 30 | "grunt-contrib-jshint": "0.x", 31 | "grunt-contrib-less": "1.x", 32 | "grunt-contrib-qunit": "0.5.x", 33 | "grunt-contrib-uglify": "0.x", 34 | "grunt-contrib-watch": "0.x", 35 | "grunt-html-validation": "0.x", 36 | "grunt-jsbeautifier": "0.x", 37 | "grunt-prompt": "1.x", 38 | "grunt-saucelabs": "8.x", 39 | "grunt-shell": "1.x", 40 | "grunt-text-replace": "0.x", 41 | "grunt-umd": "2.x", 42 | "grunt-zip": "0.x", 43 | "load-grunt-tasks": "3.x", 44 | "qunitjs": "1.x", 45 | "semver": "5.x", 46 | "serve-static": ">=1.7.2" 47 | }, 48 | "engines": { 49 | "node": "0.10.x" 50 | }, 51 | "homepage": "https://github.com/ExactTarget/fuelux", 52 | "keywords": [ 53 | "application", 54 | "bootstrap", 55 | "controls", 56 | "css", 57 | "exacttarget", 58 | "exact target", 59 | "front-end", 60 | "fuelux", 61 | "fuel ux", 62 | "js", 63 | "salesforce", 64 | "user interface", 65 | "web" 66 | ], 67 | "license": { 68 | "type": "BSD-3-Clause", 69 | "url": "https://github.com/ExactTarget/fuelux/blob/master/LICENSE" 70 | }, 71 | "main": "./dist/js/npm", 72 | "name": "fuelux", 73 | "private": false, 74 | "repository": { 75 | "type": "git", 76 | "url": "git://github.com/ExactTarget/fuelux.git" 77 | }, 78 | "scripts": { 79 | "main": "devserver.js", 80 | "start": "grunt serve", 81 | "test": "grunt travisci --verbose", 82 | "postinstall": "./postinstall.sh" 83 | }, 84 | "title": "Fuel UX", 85 | "version": "3.11.0", 86 | "volo": { 87 | "baseDir": "lib", 88 | "dependencies": { 89 | "moment": "http://momentjs.com/downloads/moment-with-locales.js" 90 | }, 91 | "type": "directory", 92 | "url": "https://raw.github.com/ExactTarget/fuelux/{version}/dist/fuelux.zip" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/loader-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | define(function(require){ 6 | var $ = require('jquery'); 7 | var html = require('text!test/markup/loader-markup.html'); 8 | 9 | require('bootstrap'); 10 | require('fuelux/loader'); 11 | 12 | module('Fuel UX Loader'); 13 | 14 | test('should be defined on jquery object', function () { 15 | ok($().loader(), 'loader method is defined'); 16 | }); 17 | 18 | test('should return element', function () { 19 | var $loader = $(html); 20 | ok($loader.loader() === $loader, 'loader is initialized'); 21 | }); 22 | 23 | asyncTest('should play on init', function(){ 24 | var $loader = $(html); 25 | 26 | $loader.loader(); 27 | setTimeout(function(){ 28 | start(); 29 | ok($loader.attr('data-frame')!==1, 'loader playing on init'); 30 | }, 160); 31 | }); 32 | 33 | asyncTest('pause should function as expected', function(){ 34 | var $loader = $(html); 35 | 36 | $loader.loader(); 37 | $loader.loader('pause'); 38 | setTimeout(function(){ 39 | start(); 40 | equal($loader.attr('data-frame'), 1, 'pause halts frame progression'); 41 | }, 160); 42 | }); 43 | 44 | asyncTest('play should function as expected', function(){ 45 | var $loader = $(html); 46 | 47 | $loader.loader(); 48 | $loader.loader('pause'); 49 | $loader.loader('play'); 50 | setTimeout(function(){ 51 | start(); 52 | ok($loader.attr('data-frame')!==1, 'play continues frame progression'); 53 | }, 160); 54 | }); 55 | 56 | asyncTest('reset should function as expected', function(){ 57 | var $loader = $(html); 58 | 59 | $loader.loader(); 60 | setTimeout(function(){ 61 | start(); 62 | $loader.loader('reset'); 63 | equal($loader.attr('data-frame'), 1, 'reset reverts frame to beginning'); 64 | }, 160); 65 | }); 66 | 67 | test('next should function as expected', function(){ 68 | var $loader = $(html); 69 | 70 | $loader.loader(); 71 | $loader.loader('pause'); 72 | $loader.loader('next'); 73 | 74 | equal($loader.attr('data-frame'), 2, 'next increments frame by 1'); 75 | }); 76 | 77 | test('prev should function as expected', function(){ 78 | var $loader = $(html); 79 | 80 | $loader.loader(); 81 | $loader.loader('pause'); 82 | $loader.loader('next'); 83 | $loader.loader('previous'); 84 | 85 | equal($loader.attr('data-frame'), 1, 'prev decrements frame by 1'); 86 | }); 87 | 88 | test("should destroy control", function () { 89 | var $el = $(html); 90 | 91 | equal(typeof( $el.loader('destroy')) , 'string', 'returns string (markup)'); 92 | equal( $el.parent().length, false, 'control has been removed from DOM'); 93 | }); 94 | 95 | }); 96 | -------------------------------------------------------------------------------- /echelon/middleware.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2011 Dennis Kaarsemaker 2 | # Small piece of middleware to be able to access authentication data from 3 | # everywhere in the django code. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, 6 | # are permitted provided that the following conditions are met: 7 | # 8 | # 1. Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # 3. Neither the name of Django nor the names of its contributors may be used 16 | # to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | import thread 31 | from django.contrib.auth.models import User 32 | 33 | class EchelonMiddleware(object): 34 | """Always have access to the current user""" 35 | __users = {} 36 | 37 | def process_request(self, request): 38 | """Store user info""" 39 | self.__class__.set_user(request.user) 40 | def process_response(self, request, response): 41 | """Delete user info""" 42 | self.__class__.del_user() 43 | return response 44 | def process_exception(self, request, exception): 45 | """Delete user info""" 46 | self.__class__.del_user() 47 | 48 | @classmethod 49 | def get_user(cls, default=None): 50 | """Retrieve user info""" 51 | return cls.__users.get(thread.get_ident(), default) 52 | 53 | @classmethod 54 | def set_user(cls, user): 55 | """Store user info""" 56 | if isinstance(user, basestring): 57 | user = User.objects.get(username=user) 58 | cls.__users[thread.get_ident()] = user 59 | 60 | @classmethod 61 | def del_user(cls): 62 | """Delete user info""" 63 | cls.__users.pop(thread.get_ident(), None) 64 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/checkbox.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .checkbox { 4 | 5 | &.highlight { 6 | 7 | // padding: 4px; 8 | 9 | & + .checkbox.highlight { 10 | margin-top: -5px; 11 | } 12 | 13 | & label.checkbox-custom { 14 | padding: 4px 4px 4px 24px; 15 | //margin-left: -8px; 16 | } 17 | 18 | &.checked label.checkbox-custom, label.checked.checkbox-custom { 19 | background: @gray90; 20 | border-radius: @baseBorderRadius; 21 | } 22 | } 23 | 24 | /* for keyboard tabbing */ 25 | input[type="checkbox"]:focus + .checkbox-label, 26 | input[type="checkbox"]:hover + .checkbox-label, 27 | .checkbox-label:hover 28 | { 29 | color: @gray60; 30 | } 31 | 32 | input[type="checkbox"]:disabled:focus + .checkbox-label, 33 | input[type="checkbox"]:disabled:hover + .checkbox-label, 34 | &.disabled label:hover 35 | { 36 | color: inherit; 37 | } 38 | 39 | } 40 | 41 | .form-horizontal .checkbox-inline { 42 | padding-top: 0; 43 | } 44 | 45 | .input-group-addon.checkbox-custom.checkbox-inline:before { 46 | left: 11px; 47 | top: 9px; 48 | } 49 | 50 | .checkbox-custom { 51 | position: relative; 52 | 53 | &:before { 54 | #fuelux > .icon-base-styles("Glyphicons Halflings"); 55 | border: 1px solid @gray67; 56 | border-radius: @baseBorderRadius; 57 | color: @true-white; 58 | content: " "; 59 | font-size: 9px; 60 | height: 14px; 61 | left: 0px; 62 | padding: 1px 0 0 1px; 63 | position: absolute; 64 | top: 3px; 65 | width: 14px; 66 | } 67 | 68 | /* for keyboard tabbing */ 69 | &:active:before, &:focus:before { 70 | color: @focusColor; 71 | cursor: pointer; 72 | box-shadow: inset 0px 0px 2px 1px @focusColor, 0px 0px 5px 0px @focusColor; 73 | } 74 | 75 | &.highlight { 76 | &:before { 77 | left: 4px; 78 | top: 6px; 79 | } 80 | } 81 | 82 | &.checked { 83 | &:before { 84 | background: @checkboxPrimaryColor; 85 | border-color: @checkboxPrimaryColor; 86 | content: "\e013"; 87 | } 88 | } 89 | 90 | &.disabled { 91 | cursor: not-allowed; 92 | opacity: .65; 93 | 94 | &:before 95 | { 96 | cursor: not-allowed; 97 | opacity: .65; 98 | } 99 | } 100 | 101 | &.checkbox-inline { 102 | &:before { 103 | left: 0; 104 | top: 3px; 105 | } 106 | 107 | &.highlight { 108 | padding: 4px 4px 4px 24px; 109 | left: -4px; 110 | 111 | &:before { 112 | left: 4px; 113 | top: 7px; 114 | } 115 | 116 | &.checked { 117 | background: @gray90; 118 | border-radius: @baseBorderRadius; 119 | } 120 | } 121 | } 122 | 123 | 124 | /* for keyboard tabbing */ 125 | input[type="checkbox"]:focus + .checkbox-label { 126 | color: @gray60; 127 | } 128 | 129 | } 130 | 131 | label.checkbox-custom.checkbox-inline { 132 | padding-left: 20px; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /myproject/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 导入cmdb.models模块 3 | import cmdb.models 4 | # 从rest_framework中导入模块 5 | from rest_framework import routers, serializers, viewsets 6 | 7 | # Server_Group, IDC, Project, Server_Role, Server_Device 8 | 9 | # 给需要生成API的model定义一个数据序列 10 | # Serializers define the API representation. 11 | class ServerGroupSerializer(serializers.HyperlinkedModelSerializer): 12 | project = serializers.StringRelatedField() 13 | 14 | class Meta: 15 | # 使用的model名称 16 | model = cmdb.models.Server_Group 17 | # 字段序列 18 | fields = ('url', 'name', 'project', 19 | 'memo') 20 | 21 | 22 | class IDCSerializer(serializers.HyperlinkedModelSerializer): 23 | class Meta: 24 | # 使用的model名称 25 | model = cmdb.models.IDC 26 | # 字段序列 27 | fields = ('url', 'name', 'memo') 28 | 29 | 30 | class ProjectSerializer(serializers.HyperlinkedModelSerializer): 31 | class Meta: 32 | model = cmdb.models.Project 33 | # 字段序列 34 | fields = ('url', 'name', 'memo') 35 | 36 | 37 | class ServerRoleSerializer(serializers.HyperlinkedModelSerializer): 38 | group = serializers.StringRelatedField() 39 | 40 | class Meta: 41 | model = cmdb.models.Server_Role 42 | # 字段序列 43 | fields = ('url', 'name', 'group', 'memo') 44 | 45 | 46 | class ServerDeviceSerializer(serializers.HyperlinkedModelSerializer): 47 | admin = serializers.StringRelatedField() 48 | idc = serializers.StringRelatedField() 49 | role = serializers.StringRelatedField(many=True) 50 | 51 | class Meta: 52 | model = cmdb.models.Server_Device 53 | # 字段序列 54 | fields = ('url', 'name', 'sn', 'public_ip', 55 | 'private_ip', 'mac', 'os', 'disk', 'mem', 'cpu', 'idc', 56 | 'role', 'status', 57 | 'admin', 'memo') 58 | 59 | 60 | # ViewSets define the view behavior. 61 | class ServerGroupViewSet(viewsets.ModelViewSet): 62 | queryset = cmdb.models.Server_Group.objects.all() 63 | serializer_class = ServerGroupSerializer 64 | 65 | 66 | class IDCViewSet(viewsets.ModelViewSet): 67 | queryset = cmdb.models.IDC.objects.all() 68 | serializer_class = IDCSerializer 69 | 70 | 71 | class ProjectViewSet(viewsets.ModelViewSet): 72 | queryset = cmdb.models.Project.objects.all() 73 | serializer_class = ProjectSerializer 74 | 75 | 76 | class ServerRoleViewSet(viewsets.ModelViewSet): 77 | queryset = cmdb.models.Server_Role.objects.all() 78 | serializer_class = ServerRoleSerializer 79 | 80 | 81 | class ServerDeviceViewSet(viewsets.ModelViewSet): 82 | queryset = cmdb.models.Server_Device.objects.all() 83 | serializer_class = ServerDeviceSerializer 84 | 85 | 86 | # Routers provide an easy way of automatically determining the URL conf. 87 | router = routers.DefaultRouter() 88 | router.register(r'server_groups', ServerGroupViewSet) 89 | router.register(r'idcs', IDCViewSet) 90 | router.register(r'projects', ProjectViewSet) 91 | router.register(r'server_roles', ServerRoleViewSet) 92 | router.register(r'server_devices', ServerDeviceViewSet) 93 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/pillbox.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .pillbox { 4 | border: 1px solid @gray74; 5 | border-radius: 4px; 6 | cursor: text; 7 | padding: 3px; 8 | 9 | &[data-readonly] { 10 | border: 1px solid transparent; 11 | 12 | &.truncate { 13 | .pillbox-input-wrap { 14 | display: inline-block; 15 | 16 | &.truncated { 17 | display: none; 18 | } 19 | } 20 | 21 | .pillbox-more { 22 | display: inline; 23 | } 24 | } 25 | 26 | .pill { 27 | span.glyphicon-close { 28 | display: none; 29 | } 30 | } 31 | 32 | .pillbox-add-item { 33 | display: none; 34 | } 35 | 36 | .pillbox-input-wrap { 37 | display: none; 38 | 39 | button.dropdown-toggle { 40 | display: none; 41 | } 42 | } 43 | } 44 | 45 | &.pills-editable { 46 | .pill-group { 47 | .pill { 48 | span { 49 | cursor: text; 50 | 51 | &.glyphicon-close { 52 | cursor: pointer; 53 | } 54 | } 55 | } 56 | } 57 | } 58 | 59 | > .pill-group { 60 | margin: 0; 61 | padding: 0; 62 | width: 100%; 63 | 64 | > .pill { 65 | margin: 2px; 66 | cursor: default; 67 | float:left; 68 | word-break: break-all; 69 | 70 | &.pillbox-highlight { 71 | outline: 1px dotted @gray60; 72 | } 73 | 74 | &.truncated { 75 | display: none; 76 | } 77 | 78 | .pillbox-list-edit { 79 | border: none; 80 | color: @gray20; 81 | font-weight: normal; 82 | border-radius: 2px; 83 | 84 | &:focus { 85 | outline: none; 86 | border: none; 87 | } 88 | } 89 | 90 | .glyphicon-close { 91 | cursor: pointer; 92 | top: -1px; 93 | left: 2px; 94 | 95 | &:before { 96 | content: " \00d7"; 97 | } 98 | 99 | &:hover { 100 | opacity: .4; 101 | } 102 | } 103 | 104 | } 105 | } 106 | 107 | .pillbox-input-wrap { 108 | position: relative; 109 | margin: 4px 0 3px 3px; 110 | float: left; 111 | 112 | &.editing { 113 | border: 1px solid @gray80; 114 | border-radius: 4px; 115 | margin: 2px 0 3px 3px; 116 | 117 | input.pillbox-add-item { 118 | border-radius: 4px; 119 | color: @gray20; 120 | height: 32px; 121 | } 122 | } 123 | } 124 | 125 | .pillbox-add-item { 126 | border: none; 127 | box-shadow: none; 128 | 129 | &:focus { 130 | outline: none; 131 | border: none; 132 | } 133 | } 134 | 135 | .pillbox-more { 136 | cursor: pointer; 137 | display: none; 138 | line-height: 30px; 139 | } 140 | 141 | .suggest { 142 | max-height: 166px; // arbitrary number 143 | overflow-y: auto; 144 | 145 | > li { 146 | white-space: nowrap; 147 | cursor: pointer; 148 | padding: 3px 20px; 149 | 150 | &.pillbox-suggest-sel { 151 | background-color: @gray93; 152 | } 153 | 154 | &:hover { 155 | background-color: @gray93; 156 | } 157 | } 158 | } 159 | input { 160 | 161 | &::-ms-clear { 162 | display:none; 163 | } 164 | } 165 | } 166 | 167 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/icons.less: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "fuelux"; 3 | src:url("@{fueluxFontPath}fuelux.eot"); 4 | src:url("@{fueluxFontPath}fuelux.eot?#iefix") format("embedded-opentype"), 5 | url(data:font-woff;base64,d09GRk9UVE8AAAUUAAsAAAAABuAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAAAegAAAIisWS2RkZGVE0AAALwAAAAGQAAABxvEtzhR0RFRgAAAwwAAAAdAAAAIAA4AARPUy8yAAADLAAAAEoAAABgL7lMbGNtYXAAAAN4AAAAPAAAAUrAGiK3aGVhZAAAA7QAAAAvAAAANgDSVuNoaGVhAAAD5AAAABwAAAAkBCkCA2htdHgAAAQAAAAAGgAAABoHmgL4bWF4cAAABBwAAAAGAAAABgALUABuYW1lAAAEJAAAAN0AAAF3kxoWmXBvc3QAAAUEAAAAEAAAACAAAwABeJw90M9rE0EUB/D30uzusLtuNTqiGIs/+gt6ifVHtgfRHqQHLTYumEsrpSSWRVNozNJc2t6S2K2bBATbS0tLe9jDUlJ6aS85hFT8H6SCFPwTZiCIbpnq6fMe8+Y7j0GIRgERlbdO9r1TBIwAwijvi/D+Ln4tuqqjq3e5erRHhetW7I/r/i90xfN4ndelOHztjgNcjMP3S3HQ41iIgX4WQ6AbrsJN6IUhGIYReApjMA6WM2c/SyQSgnuCYcF9wQPBQ8EjQVJgCkbEvudbA2AZK/gRV9DFVfyEHlaxBhpiJPlk7GX6TebdhxWDDfEb9JbaGezI9Laa74zTOyqTn9O7KosFtFdlg0ymfeE5e0X7VTZaogOqwXz+OOwM/pqbZz2vs+VwyGC/2YXwjsGWf4YBxrdfYZjhMT9M/veQwU7ZHD3MNianstmpyUb28KjROOox+OcrLnV1Nfysy0AQ6YD5Yjpf+jJxLB0Eza2WR0zFruSW5otEq7W2m3v7pJ2SFvKLubJNNPvAaVZa5ET27LXcxjzRkopVS29n9ki7Le0s+ItBmWjHE9KMnXasCjlRAs9f290gWskqpGczJNWWNnfW/WpAtB9Kq9Qs7M+SVErKb+bW7SrRgpmttGcRU64ES35xl2h/Ac9Ys4h4nGNgYGBkAILzccd+gelbXJ9hNABYswg7AAAAeJxjYGRgYOADYgkGEGBiYARCLiBmAfMYAAS4AD0AAAB4nGNgZmJgnMDAysDB6MOYxsDA4A6lvzJIMrQwMDAxsHIywIEAgskQkOaawuDwgOEBJ+OD/w8Y9Bj//v8LFGaEK1AAQkYALokNlwAAeJxjYGBgZoBgGQZGBhBwAfIYwXwWBg0gzQakGRmYGBgecP7/D1LwgAFEKzBC1QMBIxsDgjNCAQBlrAaweJxjYGRgYADiH2cX2sfz23xl4GZiAIHzt7g+w2lmBmbGv4x/gVwOBrA0AFSyC6wAeJxjYGRgYPzLwMCgx8QAAkA2IwMqYAIANwYCMQIAAAACAAADARUBhwGDAQ8AWAADAAMAXACnAAAAAFAAAAsAAHicbY49asNAEIU/2bJMsEmX1JsipYS0BAwuU/gAKdy7WAuDkPDagtzDkD5djpED5AQ5TZ7kKVJ4l9n59vHmB1jyQcJwEjLujSfMeTae8sTROJXn03jGgm/jTPdXziS9k7IcqwaeqOOD8ZRXcuNUnovxjEe+jDPpP+zpCTR632Hfh6ZXfpNUS2rYEfUNdd/sBBs6Ws5jjnIEHJ6CUnmt+N/sqnitsVJ4eSpe1KJrz5su1sH5onRrdx0p8Pkq92Uly82VtpIiJw7jCk7NhrFsQzwdutZVRXm78A9U7zY2AAAAeJxjYGZABowMaAAAAI4ABQ==) format("woff"), 6 | url("@{fueluxFontPath}fuelux.ttf") format("truetype"), 7 | url("@{fueluxFontPath}fuelux.svg#fuelux") format("svg"); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | //This could be an interesting addition... 13 | //[data-icon]:before { 14 | // #fuelux > .icon-base-styles(); 15 | // content: attr(data-icon); 16 | //} 17 | 18 | .fuelux { 19 | 20 | [class^="fueluxicon-"]:before, 21 | [class*=" fueluxicon-"]:before { 22 | #fuelux > .icon-base-styles(); 23 | } 24 | 25 | .fueluxicon-loader-full:before { 26 | content: "\e000"; 27 | } 28 | 29 | .fueluxicon-loader-1:before { 30 | content: "\e001"; 31 | } 32 | 33 | .fueluxicon-loader-2:before { 34 | content: "\e002"; 35 | } 36 | 37 | .fueluxicon-loader-3:before { 38 | content: "\e003"; 39 | } 40 | 41 | .fueluxicon-loader-4:before { 42 | content: "\e004"; 43 | } 44 | 45 | .fueluxicon-loader-5:before { 46 | content: "\e005"; 47 | } 48 | 49 | .fueluxicon-loader-6:before { 50 | content: "\e006"; 51 | } 52 | 53 | .fueluxicon-loader-7:before { 54 | content: "\e007"; 55 | } 56 | 57 | .fueluxicon-loader-8:before { 58 | content: "\e008"; 59 | } 60 | 61 | //tree 62 | 63 | .fueluxicon-bullet:before { 64 | content: "\e009"; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/radio.less: -------------------------------------------------------------------------------- 1 | .radioTabbing() { 2 | 3 | /* for keyboard tabbing */ 4 | input[type="radio"]:focus + .radio-label, 5 | input[type="radio"]:hover + .radio-label, 6 | .radio-label:hover { 7 | color: @gray60; 8 | } 9 | } 10 | 11 | .fuelux { 12 | .radio { 13 | &.highlight { 14 | padding: 4px; 15 | margin: 0 0 5px 0; 16 | 17 | & + .radio.highlight { 18 | margin-top: -9px; 19 | } 20 | & label.radio-custom { 21 | left: -8px; 22 | padding: 4px 4px 4px 24px; 23 | border-radius: @baseBorderRadius; 24 | &:before { 25 | left: 5px; 26 | top: 7px; 27 | } 28 | &:after { 29 | left: 9px; 30 | top: 11px; 31 | } 32 | } 33 | &.checked label.radio-custom, 34 | & label.radio-custom.checked { 35 | background: @gray90; 36 | border-radius: @baseBorderRadius; 37 | } 38 | } 39 | 40 | /* for keyboard tabbing */ 41 | input[type="radio"]:focus + .radio-label, 42 | input[type="radio"]:hover + .radio-label, 43 | .radio-label:hover { 44 | color: @gray60; 45 | } 46 | } 47 | .form-horizontal .radio-inline { 48 | padding-top: 0; 49 | } 50 | .input-group-addon.radio-custom.radio-inline { 51 | &:before { 52 | left: 11px; 53 | top: 9px; 54 | } 55 | &:after { 56 | left: 15px; 57 | top: 13px; 58 | } 59 | } 60 | .radio-custom { 61 | position: relative; 62 | 63 | .highlight { 64 | padding: 4px; 65 | margin: 0 0 5px 0; 66 | 67 | &.checked { 68 | background: @gray90; 69 | border-radius: @baseBorderRadius; 70 | } 71 | } 72 | &:after { 73 | background: transparent; 74 | border-radius: 6px; 75 | content: " "; 76 | height: 6px; 77 | left: 4px; 78 | position: absolute; 79 | top: 7px; 80 | width: 6px; 81 | } 82 | &:before { 83 | border: 1px solid @gray67; 84 | border-radius: 14px; 85 | content: " "; 86 | height: 14px; 87 | left: 0px; 88 | position: absolute; 89 | top: 3px; 90 | width: 14px; 91 | } 92 | &.checked { 93 | &:after { 94 | background: @true-white; 95 | } 96 | &:before { 97 | background: @checkboxPrimaryColor; 98 | border-color: @checkboxPrimaryColor; 99 | } 100 | } 101 | &.disabled { 102 | cursor: not-allowed; 103 | opacity: .65; 104 | 105 | &:after { 106 | cursor: not-allowed; 107 | } 108 | &:before { 109 | cursor: not-allowed; 110 | opacity: .65; 111 | } 112 | } 113 | &.radio-inline { 114 | &:after { 115 | left: 4px; 116 | top: 7px; 117 | } 118 | &:before { 119 | left: 0; 120 | top: 3px; 121 | } 122 | &.highlight { 123 | left: -3px; 124 | 125 | padding: 4px 4px 4px 24px; 126 | 127 | &:after { 128 | left: 8px; 129 | top: 11px; 130 | } 131 | &:before { 132 | left: 4px; 133 | top: 7px; 134 | } 135 | &.checked { 136 | background: @gray90; 137 | border-radius: @baseBorderRadius; 138 | } 139 | } 140 | } 141 | 142 | /* for keyboard tabbing */ 143 | input[type="radio"]:focus + .radio-label { 144 | color: @gray60; 145 | } 146 | } 147 | 148 | label.radio-custom.radio-inline { 149 | padding-left: 20px; 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/placard.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .placard { 4 | display: inline-block; 5 | position: relative; 6 | 7 | &[data-ellipsis="true"] { 8 | &.showing { 9 | input.placard-field { 10 | overflow: visible; 11 | text-overflow: clip; 12 | white-space: normal; 13 | } 14 | } 15 | 16 | input.placard-field { 17 | overflow: hidden; 18 | text-overflow: ellipsis; 19 | white-space: nowrap; 20 | 21 | &::-ms-clear { 22 | display:none; 23 | } 24 | } 25 | 26 | textarea.placard-field { 27 | &[readonly] { 28 | overflow: hidden; 29 | } 30 | } 31 | } 32 | 33 | &.showing { 34 | .placard-footer, 35 | .placard-header, 36 | .placard-popup { 37 | display: block; 38 | z-index: 1; 39 | } 40 | 41 | input.placard-field, textarea.placard-field { 42 | background: @true-white; 43 | border: 1px solid @gray80; 44 | box-shadow: none; 45 | position: relative; 46 | z-index: 1; 47 | } 48 | } 49 | 50 | input.placard-field, textarea.placard-field { 51 | resize: none; 52 | 53 | &[readonly] { 54 | background: @true-white; 55 | cursor: auto; 56 | 57 | &.glass { 58 | background: none; 59 | 60 | &:hover { 61 | background: @infoBackground; 62 | cursor: pointer; 63 | } 64 | } 65 | } 66 | 67 | &:focus { 68 | border: 1px solid @gray80; 69 | box-shadow: none; 70 | } 71 | } 72 | 73 | &-cancel { 74 | font-size: 12px; 75 | margin-right: 4px; 76 | vertical-align: middle; 77 | } 78 | 79 | &-footer, 80 | &-header { 81 | display: none; 82 | left: 0; 83 | line-height: 1; 84 | position: absolute; 85 | right: 0; 86 | } 87 | 88 | &-footer { 89 | padding: 4px 0 8px 0; 90 | text-align: right; 91 | top: 100%; 92 | } 93 | 94 | &-header { 95 | bottom: 100%; 96 | padding: 8px 0 4px 0; 97 | 98 | h1, h2, h3, h4, h5, h6 { 99 | margin: 0; 100 | } 101 | } 102 | 103 | &-popup { 104 | background: @infoBackground; 105 | background-clip: padding-box; 106 | border: 1px solid @gray80; 107 | border-radius: 4px; 108 | bottom: -8px; 109 | box-shadow: 0 0 0 1px @true-white inset; 110 | display: none; 111 | left: -8px; 112 | position: absolute; 113 | right: -8px; 114 | top: -8px; 115 | } 116 | 117 | .glass { 118 | background: transparent; 119 | border: 1px solid @true-white; 120 | box-shadow: none; 121 | 122 | &:hover { 123 | background: @infoBackground; 124 | border-color: @focusColor; 125 | cursor: pointer; 126 | 127 | &[disabled] { 128 | background: transparent; 129 | border-color: @true-white; 130 | cursor: not-allowed; 131 | } 132 | } 133 | 134 | &:focus { 135 | background: @true-white; 136 | border-color: @focusColor; 137 | box-shadow: inset 0 1px 1px fade(@true-black, 75%), 0 0 8px fade(@focusColor, 60%); 138 | cursor: auto; 139 | 140 | &[disabled] { 141 | background: transparent; 142 | border-color: @true-white; 143 | cursor: not-allowed; 144 | } 145 | } 146 | 147 | &[disabled] { 148 | cursor: not-allowed; 149 | } 150 | } 151 | } 152 | 153 | } -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/tree-markup.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 |
        6 | 7 | 18 | 19 | 25 |
      26 | 27 |
        28 | 29 | 40 | 41 | 47 |
      48 | 49 |
      50 |
      51 | 52 |
      53 | 54 |
      55 | 56 |
        57 | 58 | 69 | 70 | 76 |
      77 | 78 |
      79 |
      -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/combobox-markup.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 |
      6 | 7 | 24 | 25 |
      26 |
      27 | 28 | 39 | 40 | 41 |
      42 | 43 |
      44 | 45 | 62 | 63 |
      64 |
      65 | 66 |
      67 | 68 |
      69 | 70 | 86 | 87 |
      88 |
      89 |
      -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/markup/datepicker.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 | 4 |
      5 | 9 | 77 |
      78 |
      79 |
      80 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/markup/datepicker-markup.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 | 4 |
      5 | 9 | 77 |
      78 |
      79 |
      80 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // For clearing floats 2 | .clearfix { 3 | *zoom: 1; 4 | &:before, 5 | &:after { 6 | display: table; 7 | content: ""; 8 | // Fixes Opera/contenteditable bug: 9 | // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 10 | line-height: 0; 11 | } 12 | &:after { 13 | clear: both; 14 | } 15 | } 16 | 17 | #fuelux { 18 | // Single side border-radius 19 | .border-top-radius(@radius) { 20 | border-top-right-radius: @radius; 21 | border-top-left-radius: @radius; 22 | } 23 | .border-right-radius(@radius) { 24 | border-bottom-right-radius: @radius; 25 | border-top-right-radius: @radius; 26 | } 27 | .border-bottom-radius(@radius) { 28 | border-bottom-right-radius: @radius; 29 | border-bottom-left-radius: @radius; 30 | } 31 | .border-left-radius(@radius) { 32 | border-bottom-left-radius: @radius; 33 | border-top-left-radius: @radius; 34 | } 35 | 36 | // Gradient Bar Colors for buttons and alerts 37 | .gradient-bar(@primaryColor, @secondaryColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { 38 | color: @textColor; 39 | text-shadow: @textShadow; 40 | #gradient > .vertical(@primaryColor, @secondaryColor); 41 | border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%); 42 | border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); 43 | } 44 | 45 | // Gradients 46 | .vertical(@startColor: @gray33, @endColor: @gray20) { 47 | background-color: mix(@startColor, @endColor, 60%); 48 | background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ 49 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ 50 | background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ 51 | background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 52 | background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10 53 | background-repeat: repeat-x; 54 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down 55 | } 56 | 57 | // Icon Base Styles 58 | .icon-base-styles(@fontFamily: "fuelux"){ 59 | font-family: @fontFamily !important; 60 | font-style: normal !important; 61 | font-weight: normal !important; 62 | font-variant: normal !important; 63 | text-transform: none !important; 64 | line-height: 1; 65 | speak: none; 66 | -webkit-font-smoothing: antialiased; 67 | -moz-osx-font-smoothing: grayscale; 68 | } 69 | 70 | // Disables selection of text 71 | .no-selection-allowed(){ 72 | -webkit-user-select: none; 73 | -moz-user-select: none; 74 | -ms-user-select: none; 75 | -o-user-select: none; 76 | user-select: none; 77 | } 78 | 79 | // Opacity 80 | .opacity(@opacity) { 81 | opacity: @opacity / 100; 82 | filter: ~"alpha(opacity=@{opacity})"; 83 | } 84 | 85 | // Helpers 86 | // ------------------------- 87 | .data-label() { 88 | text-transform: uppercase; 89 | font-size: 10px; 90 | margin-bottom: 2px; 91 | text-shadow: 0 1px @true-white; 92 | color: @gray40; 93 | } 94 | 95 | .data-value() { 96 | font-size: 14px; 97 | } 98 | 99 | .section-heading() { 100 | font-size: 16px; 101 | color: @gray20; 102 | margin: 0 0 10px; 103 | padding: 0; 104 | text-shadow: 0 1px @true-white; 105 | } 106 | 107 | .text-emphasis-variant(@color) { 108 | color: @color; 109 | &:hover { 110 | color: darken(@color, 10%); 111 | } 112 | } 113 | 114 | .vertical-align() { 115 | margin: auto; 116 | position: absolute; 117 | top: 0; 118 | bottom: 0; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/tree.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | .tree { 4 | border: 1px solid @gray60; 5 | border-radius: 4px 4px 4px 4px; 6 | padding: 10px 15px 0 15px; 7 | overflow-x: auto; 8 | overflow-y: auto; 9 | position: relative; 10 | list-style: none; 11 | 12 | *:focus { 13 | outline: none; 14 | } 15 | 16 | button:focus { 17 | color: @treeHoverText; 18 | } 19 | 20 | ul { 21 | padding-left: 0; 22 | margin-top: 0; 23 | margin-bottom: 0; 24 | list-style: none; 25 | } 26 | 27 | li { 28 | margin: 0; 29 | margin-top: 5px; 30 | margin-bottom: 5px; 31 | } 32 | 33 | .tree-loader { 34 | // make even with tree-branch-children 35 | margin-left: 45px; 36 | } 37 | 38 | .tree-open > .tree-branch-header .glyphicon-play { 39 | transform:rotate(90deg); 40 | -ms-transform:rotate(90deg); 41 | -webkit-transform:rotate(90deg); 42 | position: relative; 43 | } 44 | 45 | [data-children=false] > .tree-branch-header .icon-caret:before { 46 | content: '\00a0'; //space 47 | } 48 | 49 | .tree-branch { 50 | 51 | .tree-branch-header { 52 | position: relative; 53 | border-radius: 6px; 54 | white-space: nowrap; 55 | 56 | .tree-branch-name:hover { 57 | color: @treeHoverText; 58 | } 59 | 60 | .glyphicon-play { 61 | font-size: 10px; 62 | padding-right: 5px; 63 | padding-left: 7px; 64 | 65 | &:before { 66 | position: relative; 67 | top: -2px; 68 | } 69 | 70 | } 71 | 72 | .tree-branch-name { 73 | white-space: nowrap; 74 | border-radius: 6px; 75 | background-color: transparent; 76 | border: 0; 77 | } 78 | 79 | label { 80 | font-weight: normal; 81 | padding-left: 3px; 82 | margin-bottom: 0; 83 | cursor: pointer; 84 | } 85 | 86 | } 87 | 88 | .tree-branch-children { 89 | margin-left: 14px; 90 | } 91 | &[haschildren='false'] { 92 | .icon-caret { 93 | visibility: hidden; 94 | } 95 | } 96 | 97 | } 98 | 99 | .tree-item { 100 | white-space: nowrap; 101 | position: relative; 102 | cursor: pointer; 103 | border-radius: 6px; 104 | margin-left: 26px; 105 | 106 | .tree-item-name { 107 | white-space: nowrap; 108 | border-radius: 6px; 109 | background-color: transparent; 110 | border: 0; 111 | } 112 | 113 | .tree-item-name:hover { 114 | color: @treeHoverText; 115 | } 116 | 117 | &.tree-selected .tree-item-name { 118 | background-color: @treeSelectBackground; 119 | color: @gray20; 120 | } 121 | 122 | label { 123 | font-weight: normal; 124 | padding-left: 7px; 125 | margin-bottom: 0; 126 | cursor: pointer; 127 | } 128 | 129 | } 130 | 131 | .icon-caret:hover + .tree-branch-name { 132 | color: @treeHoverText; 133 | } 134 | 135 | // - - - - - - - - - - - - - - 136 | // folder selectable option 137 | // - - - - - - - - - - - - - - 138 | 139 | &.tree-folder-select { 140 | 141 | .tree-branch { 142 | 143 | .icon-caret { 144 | background-color: transparent; 145 | border: 0; 146 | } 147 | 148 | .icon-caret:hover { 149 | cursor: pointer; 150 | color: @treeHoverText; 151 | } 152 | 153 | > .tree-branch-name { 154 | padding: 1px 5px 0 5px; 155 | border-radius: 6px; 156 | 157 | 158 | &.tree-selected { 159 | background-color: @treeSelectBackground; 160 | } 161 | } 162 | 163 | } 164 | 165 | .tree-branch.tree-selected > .tree-branch-header .tree-branch-name { 166 | background-color: @treeSelectBackground; 167 | 168 | &:hover { 169 | background-color: @treeSelectBackground; 170 | } 171 | } 172 | 173 | } 174 | 175 | } 176 | 177 | } -------------------------------------------------------------------------------- /echelon/fields.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2011 Dennis Kaarsemaker 2 | # 2011 Atamert Olcgen 3 | # Small piece of middleware to be able to access authentication data from 4 | # everywhere in the django code. 5 | # 6 | # Redistribution and use in source and binary forms, with or without modification, 7 | # are permitted provided that the following conditions are met: 8 | # 9 | # 1. Redistributions of source code must retain the above copyright notice, 10 | # this list of conditions and the following disclaimer. 11 | # 12 | # 2. Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 16 | # 3. Neither the name of Django nor the names of its contributors may be used 17 | # to endorse or promote products derived from this software without 18 | # specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | from django.conf import settings 32 | from django.contrib.auth.models import User 33 | from django.db.models import SubfieldBase 34 | from django.db.models.fields import TextField 35 | from django.db.models.fields.related import ForeignKey, ManyToOneRel 36 | from echelon.middleware import EchelonMiddleware 37 | import json 38 | 39 | 40 | if 'echelon' not in settings.INSTALLED_APPS: 41 | raise ValueError("Echelon middleware is not enabled") 42 | 43 | 44 | # Register fields with south, if installed 45 | if 'south' in settings.INSTALLED_APPS: 46 | from south.modelsinspector import add_introspection_rules 47 | add_introspection_rules([], ["^echelon\.fields\.CurrentUserField"]) 48 | add_introspection_rules([], ["^echelon\.fields\.ChangelogField"]) 49 | 50 | 51 | class CurrentUserField(ForeignKey): 52 | def __init__(self, to_field=None, rel_class=ManyToOneRel, **kwargs): 53 | self.add_only = kwargs.pop('add_only', False) 54 | kwargs.update({ 55 | 'editable': False, 56 | 'null': True, 57 | 'rel_class': rel_class, 58 | 'to': User, 59 | 'to_field': to_field, 60 | }) 61 | super(CurrentUserField, self).__init__(**kwargs) 62 | 63 | def pre_save(self, model_instance, add): 64 | if add or not self.add_only: 65 | user = EchelonMiddleware.get_user() 66 | if user and user.is_authenticated(): 67 | # Do something for authenticated users. 68 | setattr(model_instance, self.attname, user.pk) 69 | return user.pk 70 | 71 | return super(CurrentUserField, self).pre_save(model_instance, add) 72 | 73 | 74 | class ChangelogField(TextField): 75 | __metaclass__ = SubfieldBase 76 | marker = '__Echelon_ChangelogField' 77 | 78 | def to_python(self, value): 79 | if isinstance(value, basestring): 80 | if value.startswith(self.marker): 81 | return json.loads(str(value[len(self.marker):])) 82 | return value 83 | 84 | def get_prep_value(self, value): 85 | return self.marker + json.dumps(value, ) 86 | -------------------------------------------------------------------------------- /cmdb/models.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # encoding:utf8 3 | # 从django.db中导入models模块 4 | from django.db import models 5 | # 导入User模块 6 | from django.contrib.auth.models import User 7 | # Create your models here. 8 | # 定义一个Server_Group类,从models.Model中继承,这里也就是所谓得数据表结构 9 | class Server_Group(models.Model): 10 | # 定义主机组名称字段 11 | name = models.CharField(u'主机组', max_length=255, unique=True) 12 | # 关联的项目字段,这是关联一个外键 13 | project = models.ForeignKey("Project", verbose_name='项目名称') 14 | # 备注字段 15 | memo = models.CharField(u'备注', max_length=255, blank=True) 16 | # unicode返回值 17 | def __unicode__(self): 18 | # 返回的格式 19 | return '%s-%s' % (self.project.name, self.name) 20 | 21 | # 定义Meta属性 22 | class Meta: 23 | # 数据库中的表名 24 | db_table = 'server_group' 25 | # 存储的时候确认组合键唯一 26 | unique_together = (("name", "project"),) 27 | 28 | 29 | # 定义一个IDC类,主要存储IDC信息,数据表结构有2个字段 30 | class IDC(models.Model): 31 | # 定义IDC的名称字段 32 | name = models.CharField(u'IDC名称', max_length=255, unique=True) 33 | memo = models.CharField(u'备注', max_length=255, blank=True) 34 | 35 | def __unicode__(self): 36 | return self.name 37 | 38 | class Meta: 39 | db_table = 'idc' 40 | 41 | 42 | # 定义一个Project类,主要存储项目信息,数据表结构有2个字段 43 | class Project(models.Model): 44 | name = models.CharField(u'项目名称', max_length=255, unique=True) 45 | memo = models.CharField(u'备注', max_length=255, blank=True) 46 | 47 | def __unicode__(self): 48 | return self.name 49 | 50 | class Meta: 51 | db_table = 'project' 52 | 53 | 54 | # 定义一个Server_Role类,主要存储服务器角色信息,数据表结构有3个字段 55 | class Server_Role(models.Model): 56 | name = models.CharField(u'角色', max_length=255) 57 | # 关联Server_Group,也就是服务器组 58 | group = models.ForeignKey("Server_Group", verbose_name='项目组') 59 | memo = models.CharField(u'备注', max_length=255, blank=True) 60 | 61 | def __unicode__(self): 62 | return '%s-%s-%s' % (self.group.project.name, self.group.name, self.name) 63 | 64 | class Meta: 65 | # 设置数据库表名 66 | db_table = 'server_role' 67 | # 存储的时候确认组合键唯一 68 | unique_together = (("name", "group"),) 69 | 70 | 71 | # CMDB核心数据表结构,用来存在服务器系统信息 72 | class Server_Device(models.Model): 73 | # 服务器状态选择,具体的字段存储数据为0-3的int数字 74 | SERVER_STATUS = ( 75 | (0, u'下线'), 76 | (1, u'在线'), 77 | (2, u'待上线'), 78 | (3, u'测试'), 79 | ) 80 | # 定义一个名称字段,blank没有设置默认为False不能为空,且unique=True必须唯一 81 | name = models.CharField(u'主机名称', max_length=100, unique=True) 82 | # 定义SN编号字段, blank=True可以为空 83 | sn = models.CharField(u'SN号', max_length=200, blank=True) 84 | # 公网IP字段,可以为空 85 | public_ip = models.CharField(u'外网IP', max_length=200, blank=True) 86 | # 私网IP,可以为空 87 | private_ip = models.CharField(u'内网IP', max_length=200, blank=True) 88 | # 定义mac地址字段 89 | mac = models.CharField(u'MAC地址', max_length=200, blank=True) 90 | # 定义操作系统字段 91 | os = models.CharField(u'操作系统', max_length=200, blank=True) 92 | # 定义磁盘信息字段 93 | disk = models.CharField(u'磁盘', max_length=200, blank=True) 94 | # 定义内存信息字段 95 | mem = models.CharField(u'内存', max_length=200, blank=True) 96 | # 定义CPU信息字段 97 | cpu = models.CharField(u'CPU', max_length=200, blank=True) 98 | # 关联IDC信息 99 | idc = models.ForeignKey(IDC, max_length=255, blank=True, null=True, verbose_name='机房名称') 100 | # 定义个多对多字段,一台服务器可以对应多一个角色 101 | role = models.ManyToManyField("Server_Role", verbose_name='角色', blank=True) 102 | # 机器状态,默认都为在线状态 103 | status = models.SmallIntegerField(verbose_name='机器状态', choices=SERVER_STATUS, default=1) 104 | # 管理用户信息 105 | admin = models.ForeignKey('auth.User', verbose_name='管理员', null=True, blank=True) 106 | # 定义备注字段 107 | memo = models.CharField(u'备注', max_length=200, blank=True) 108 | 109 | def __unicode__(self): 110 | return self.name 111 | 112 | class Meta: 113 | db_table = 'server_device' 114 | -------------------------------------------------------------------------------- /cmdb/base_admin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding:utf8 3 | 4 | from models import * 5 | from model_form import * 6 | from django.contrib.auth.models import User, Permission 7 | 8 | # 定义模板 9 | BASE_ADMIN = { 10 | 'server_device': { 11 | 'model': Server_Device, 12 | 'form': Server_Device_CheckForm, 13 | 'name': u'主机', 14 | 'import': 'open', 15 | 'list_display': ['name', 16 | 'sn', 17 | 'public_ip', 18 | 'private_ip', 19 | 'mac', 20 | 'os', 21 | 'disk', 22 | 'cpu', 23 | 'idc', 24 | 'role', 25 | 'status', 26 | 'admin', 27 | 'memo'], 28 | 'readonly': ['name'], 29 | 'action_list': [(u'编辑', 'pencil', '/cmdb/server_device/modify/'),] 30 | }, 31 | 32 | 'idc': { 33 | 'model': IDC, 34 | 'form': IDC_CheckForm, 35 | 'name': u'IDC', 36 | 'import': '', 37 | 'list_display': ['name', 38 | 'memo'], 39 | 'action_list': [(u'编辑', 'pencil', '/cmdb/idc/modify/'),] 40 | }, 41 | 42 | 'project': { 43 | 'model': Project, 44 | 'form': Project_CheckForm, 45 | 'name': u'项目', 46 | 'import': '', 47 | 'list_display': ['name', 48 | 'memo'], 49 | 'action_list': [(u'编辑', 'pencil', '/cmdb/project/modify/'),] 50 | }, 51 | 52 | 'server_group': { 53 | 'model': Server_Group, 54 | 'form': Server_Group_CheckForm, 55 | 'name': u'项目组', 56 | 'import': '', 57 | 'list_display': ['name', 58 | 'project', 59 | 'memo'], 60 | 'action_list': [(u'编辑', 'pencil', '/cmdb/server_group/modify/'),] 61 | }, 62 | 63 | 'server_role': { 64 | 'model': Server_Role, 65 | 'form': Server_Role_CheckForm, 66 | 'name': u'主机角色', 67 | 'import': '', 68 | 'list_display': ['name', 69 | 'group', 70 | 'memo'], 71 | 'action_list': [(u'编辑', 'pencil', '/cmdb/server_role/modify/'),] 72 | }, 73 | 74 | 'user': { 75 | # model名称 76 | 'model': User, 77 | # form表单 78 | 'form': User_CheckFrom, 79 | # 名称 80 | 'name': u'用户管理', 81 | # 是否可以导入信息 82 | 'import': '', 83 | # table展示字段 84 | 'list_display': ['username', 85 | 'password', 86 | 'email', 87 | 'is_superuser', 88 | 'is_active', 89 | 'is_staff', 90 | 'groups', 91 | 'user_permissions'], 92 | # 编辑的时候只读字段 93 | 'readonly': ['username', ], #'password' 94 | # 动作 95 | 'action_list': [(u'编辑', 'pencil', '/cmdb/user/modify/'),] 96 | }, 97 | 98 | 'group': { 99 | # model名称 100 | 'model': Group, 101 | # form表单 102 | 'form': Group_CheckFrom, 103 | # 名称 104 | 'name': u'用户组管理', 105 | # 是否可以导入信息 106 | 'import': '', 107 | # table展示字段 108 | 'list_display': ['name', 109 | 'permissions'], 110 | # 编辑的时候只读字段 111 | 'readonly': ['name', ], 112 | # 动作 113 | 'action_list': [(u'编辑', 'pencil', '/cmdb/group/modify/'),] 114 | }, 115 | 116 | 'permission': { 117 | 'model': Permission, 118 | 'form': Project_CheckForm, 119 | 'name': u'权限管理', 120 | 'import': '', 121 | 'list_display': ['name', 122 | 'content_type', 123 | 'codename'], 124 | 'action_list': [(u'编辑', 'pencil', '/cmdb/permission/modify/'),] 125 | } 126 | 127 | 128 | } 129 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/test/browser-globals.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | ( function() { 6 | 7 | $(function () { 8 | 9 | module('FuelUX Component Initialization (via Browser Globals)', { 10 | setup: function () { 11 | this.elems = $('#qunit-fixture').children(); 12 | } 13 | }); 14 | 15 | // Needed for saucelab testing 16 | var log = []; 17 | var testName; 18 | 19 | QUnit.done(function (test_results) { 20 | var tests = []; 21 | for (var i = 0, len = log.length; i < len; i++) { 22 | var details = log[i]; 23 | tests.push({ 24 | name: details.name, 25 | result: details.result, 26 | expected: details.expected, 27 | actual: details.actual, 28 | source: details.source 29 | }); 30 | } 31 | test_results.tests = tests; 32 | 33 | window.global_test_results = test_results; 34 | }); 35 | QUnit.testStart(function (testDetails) { 36 | QUnit.log = function (details) { 37 | if (!details.result) { 38 | details.name = testDetails.name; 39 | log.push(details); 40 | } 41 | }; 42 | }); 43 | 44 | // In order to be be UMD compliant, modules must work with 45 | // AMD (require.js) and as browser globals. The following tests 46 | // check to see if the only the browser global is present 47 | // and nothing else. 48 | 49 | test('checkbox should be defined on jQuery object', function () { 50 | ok($().checkbox, 'checkbox method is defined'); 51 | }); 52 | 53 | test('combobox should be defined on jQuery object', function () { 54 | ok($().combobox, 'combobox method is defined'); 55 | }); 56 | 57 | test('datepicker should be defined on the jQuery object', function () { 58 | ok($().datepicker, 'datepicker method is defined'); 59 | }); 60 | 61 | test('dropdownautoflip should be defined on the jQuery object', function () { 62 | ok($().dropdownautoflip, 'dropdownautoflip method is defined'); 63 | }); 64 | 65 | test('infinitescroll should be defined on the jQuery object', function () { 66 | ok($().infinitescroll, 'infinitescroll method is defined'); 67 | }); 68 | 69 | test('loader should be defined on the jQuery object', function () { 70 | ok($().loader, 'loader method is defined'); 71 | }); 72 | 73 | test('pillbox should be defined on jQuery object', function () { 74 | ok($().pillbox, 'pillbox method is defined'); 75 | }); 76 | 77 | test('radio should be defined on jQuery object', function () { 78 | ok($().radio, 'radio method is defined'); 79 | }); 80 | 81 | test('repeater should be defined on jQuery object', function () { 82 | ok($().repeater, 'repeater method is defined'); 83 | }); 84 | 85 | test('repeater list should be defined on jQuery object', function () { 86 | ok($.fn.repeater.viewTypes.list, 'repeater list view is defined'); 87 | }); 88 | 89 | test('repeater thumbnail should be defined on jQuery object', function () { 90 | ok($.fn.repeater.viewTypes.thumbnail, 'repeater thumbnail view is defined'); 91 | }); 92 | 93 | test('scheduler should be defined on the jQuery object', function () { 94 | ok($().scheduler, 'scheduler method is defined'); 95 | }); 96 | 97 | test('search should be defined on jQuery object', function () { 98 | ok($().search, 'search method is defined'); 99 | }); 100 | 101 | test('selectlist should be defined on jQuery object', function () { 102 | ok($().selectlist, 'selectlist method is defined'); 103 | }); 104 | 105 | test('spinbox should be defined on jQuery object', function () { 106 | ok($().spinbox, 'spinbox method is defined'); 107 | }); 108 | 109 | test('tree should be defined on jQuery object', function () { 110 | ok($().tree, 'tree method is defined'); 111 | }); 112 | 113 | test('wizard should be defined on jQuery object', function () { 114 | ok($().wizard, 'wizard method is defined'); 115 | }); 116 | 117 | }); 118 | 119 | })(); -------------------------------------------------------------------------------- /myproject/settings.py: -------------------------------------------------------------------------------- 1 | #encoding: utf8 2 | """ 3 | Django settings for myproject project. 4 | 5 | For more information on this file, see 6 | https://docs.djangoproject.com/en/1.7/topics/settings/ 7 | 8 | For the full list of settings and their values, see 9 | https://docs.djangoproject.com/en/1.7/ref/settings/ 10 | """ 11 | CMDB_VERSION = '1.0' 12 | CMDB_NAME = u'测试CMDB' 13 | 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | import os 17 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = 'la-g+o%64a_@g_c990x%w4da9hxcu_wu3_f_afku(hc8i^vgjh' 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | TEMPLATE_DEBUG = True 30 | 31 | ALLOWED_HOSTS = [] 32 | 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = ( 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'cmdb', 44 | 'echelon', 45 | 'rest_framework' 46 | ) 47 | 48 | REST_FRAMEWORK = { 49 | # Use Django's standard `django.contrib.auth` permissions, 50 | # or allow read-only access for unauthenticated users. 51 | 'DEFAULT_PERMISSION_CLASSES': [ 52 | 'rest_framework.permissions.IsAuthenticated' 53 | ] 54 | } 55 | 56 | MIDDLEWARE_CLASSES = ( 57 | 'django.contrib.sessions.middleware.SessionMiddleware', 58 | 'django.middleware.common.CommonMiddleware', 59 | 'django.middleware.csrf.CsrfViewMiddleware', 60 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 61 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 62 | 'django.contrib.messages.middleware.MessageMiddleware', 63 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 64 | 'echelon.middleware.EchelonMiddleware', 65 | ) 66 | 67 | TEMPLATE_CONTEXT_PROCESSORS = ( 68 | 'django.core.context_processors.static', 69 | 'cmdb.context_processors.menu', 70 | "django.contrib.auth.context_processors.auth", 71 | "django.core.context_processors.request", 72 | ) 73 | 74 | ROOT_URLCONF = 'myproject.urls' 75 | 76 | WSGI_APPLICATION = 'myproject.wsgi.application' 77 | 78 | 79 | # Database 80 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 81 | 82 | DATABASES = { 83 | 'default': { 84 | 'ENGINE': 'django.db.backends.mysql', 85 | 'NAME': 'opencmdb', 86 | 'HOST': '127.0.0.1', 87 | 'USER': 'opencmdb', 88 | 'PASSWORD': 'opencmdb', 89 | 'PORT': '3306', 90 | 'OPTIONS': {'charset': 'utf8', } 91 | } 92 | } 93 | 94 | # Internationalization 95 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ 96 | 97 | LANGUAGE_CODE = 'en-us' 98 | 99 | TIME_ZONE = 'Asia/Shanghai' 100 | 101 | USE_I18N = True 102 | 103 | USE_L10N = True 104 | 105 | USE_TZ = True 106 | 107 | 108 | # Static files (CSS, JavaScript, Images) 109 | # https://docs.djangoproject.com/en/1.7/howto/static-files/ 110 | 111 | STATIC_URL = '/static/' 112 | 113 | STATICFILES_DIRS = ( 114 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 115 | # Always use forward slashes, even on Windows. 116 | # Don't forget to use absolute paths, not relative paths. 117 | os.path.join(BASE_DIR, 'static/'), 118 | ) 119 | 120 | TEMPLATE_DIRS = [ 121 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 122 | # Always use forward slashes, even on Windows. 123 | # Don't forget to use absolute paths, not relative paths. 124 | os.path.join(BASE_DIR, 'templates'), 125 | ] 126 | 127 | LOGIN_URL = '/login/' 128 | LOGIN_REDIRECT_URL = '/home/' 129 | try: 130 | LOCAL_SETTINGS 131 | except NameError: 132 | try: 133 | from local_settings import * 134 | except ImportError: 135 | print "Warning: import local settings." 136 | -------------------------------------------------------------------------------- /echelon/views.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011 Dennis Kaarsemaker 2 | # Small piece of middleware to be able to access authentication data from 3 | # everywhere in the django code. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, 6 | # are permitted provided that the following conditions are met: 7 | # 8 | # 1. Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # 3. Neither the name of Django nor the names of its contributors may be used 16 | # to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | from django.contrib.auth.decorators import user_passes_test 31 | from django.contrib.contenttypes.models import ContentType 32 | from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage, InvalidPage 33 | from django.db.models import Q 34 | from django.contrib.auth.models import User 35 | from django.shortcuts import render_to_response 36 | from django.template import RequestContext 37 | from echelon.models import ChangelogEntry 38 | from utils.model_utils import get_page_choices 39 | import json 40 | 41 | 42 | @user_passes_test(lambda user: user.is_staff) 43 | def changelog(request): 44 | log = ChangelogEntry.objects.all() 45 | selected = request.GET.get('content_type', '').strip() 46 | changes = request.GET.get('changes', '').strip() 47 | who = request.GET.get('who', '').strip() 48 | detail = request.GET.get('detail', '').strip() 49 | if selected: 50 | log = log.filter(content_type=selected) 51 | 52 | if who: 53 | log = log.filter(who__username=who) 54 | 55 | if changes: 56 | log = log.filter(Q(changes__contains=changes) | 57 | Q(action=changes) | 58 | Q(before_change__contains=changes) | 59 | Q(after_change__contains=changes)) 60 | paginator = Paginator(log.order_by('-timestamp'), 15) 61 | 62 | page_n = request.GET.get('p', '1') 63 | if not page_n.isdigit(): 64 | page_n = '1' 65 | page_n = int(page_n) 66 | 67 | try: 68 | page = paginator.page(page_n) 69 | except (EmptyPage, InvalidPage): 70 | page = paginator.page(paginator.num_pages) 71 | modelnames = [str('%s.%s' % (m.app_label, m.model)) for m in ContentType.objects.order_by('app_label', 'model')] 72 | modelnames = json.dumps(modelnames) 73 | 74 | users = [u['username'] for u in User.objects.all().values('username')] 75 | users = json.dumps(users) 76 | ctx = RequestContext(request, { 77 | 'models': modelnames, 78 | 'selected': selected, 79 | 'who': who, 80 | 'changes': changes, 81 | 'users': users, 82 | 'detail': detail, 83 | 84 | 'page': page, 85 | 'page_pre': page.has_previous(), 86 | 'page_next': page.has_next(), 87 | 'paginator': paginator, 88 | 'page_n': page_n, 89 | 'page_choices': get_page_choices(page_n, paginator.num_pages), 90 | }) 91 | return render_to_response('echelon/changelog.html', ctx) 92 | -------------------------------------------------------------------------------- /static/plugins/fuelux-3.11.0/less/utility.less: -------------------------------------------------------------------------------- 1 | .fuelux { 2 | 3 | // Font Family 4 | // ------------------------- 5 | .serif { 6 | font-family: @serifFontFamily; 7 | } 8 | .monospace { 9 | font-family: @monoFontFamily; 10 | } 11 | 12 | .text-sm { 13 | font-size: @fontSizeSmall; 14 | } 15 | .text-lg { 16 | font-size: @fontSizeLarge; 17 | } 18 | 19 | // Padding 20 | // ------------------------- 21 | .padding { 22 | &-xs { 23 | padding: @padding-xs; 24 | &-horizontal { 25 | padding: 0 @padding-xs; 26 | } 27 | &-vertical { 28 | padding: @padding-xs 0; 29 | } 30 | &-top { 31 | padding-top: @padding-xs; 32 | } 33 | &-bottom { 34 | padding-bottom: @padding-xs; 35 | } 36 | &-left { 37 | padding-left: @padding-xs; 38 | } 39 | &-right { 40 | padding-right: @padding-xs; 41 | } 42 | } 43 | &-sm { 44 | padding: @padding-sm; 45 | &-horizontal { 46 | padding: 0 @padding-sm; 47 | } 48 | &-vertical { 49 | padding: @padding-sm 0; 50 | } 51 | &-top { 52 | padding-top: @padding-sm; 53 | } 54 | &-bottom { 55 | padding-bottom: @padding-sm; 56 | } 57 | &-left { 58 | padding-left: @padding-sm; 59 | } 60 | &-right { 61 | padding-right: @padding-sm; 62 | } 63 | } 64 | &-md { 65 | padding: @padding-md; 66 | &-horizontal { 67 | padding: 0 @padding-md; 68 | } 69 | &-vertical { 70 | padding: @padding-md 0; 71 | } 72 | &-top { 73 | padding-top: @padding-md; 74 | } 75 | &-bottom { 76 | padding-bottom: @padding-md; 77 | } 78 | &-left { 79 | padding-left: @padding-md; 80 | } 81 | &-right { 82 | padding-right: @padding-md; 83 | } 84 | } 85 | &-lg { 86 | padding: @padding-lg; 87 | &-horizontal { 88 | padding: 0 @padding-lg; 89 | } 90 | &-vertical { 91 | padding: @padding-lg 0; 92 | } 93 | &-top { 94 | padding-top: @padding-lg; 95 | } 96 | &-bottom { 97 | padding-bottom: @padding-lg; 98 | } 99 | &-left { 100 | padding-left: @padding-lg; 101 | } 102 | &-right { 103 | padding-right: @padding-lg; 104 | } 105 | } 106 | } 107 | 108 | // Margin 109 | // ------------------------- 110 | .margin { 111 | &-xs { 112 | margin: @margin-xs; 113 | 114 | &-horizontal { 115 | margin: 0 @margin-xs; 116 | } 117 | &-vertical { 118 | margin: @margin-xs 0; 119 | } 120 | &-top { 121 | margin-top: @margin-xs; 122 | } 123 | &-bottom { 124 | margin-bottom: @margin-xs; 125 | } 126 | &-left { 127 | margin-left: @margin-xs; 128 | } 129 | &-right { 130 | margin-right: @margin-xs; 131 | } 132 | } 133 | &-sm { 134 | margin: @margin-sm; 135 | &-horizontal { 136 | margin: 0 @margin-sm; 137 | } 138 | &-vertical { 139 | margin: @margin-sm 0; 140 | } 141 | &-top { 142 | margin-top: @margin-sm; 143 | } 144 | &-bottom { 145 | margin-bottom: @margin-sm; 146 | } 147 | &-left { 148 | margin-left: @margin-sm; 149 | } 150 | &-right { 151 | margin-right: @margin-sm; 152 | } 153 | } 154 | &-md { 155 | margin: @margin-md; 156 | &-horizontal { 157 | margin: 0 @margin-md; 158 | } 159 | &-vertical { 160 | margin: @margin-md 0; 161 | } 162 | &-top { 163 | margin-top: @margin-md; 164 | } 165 | &-bottom { 166 | margin-bottom: @margin-md; 167 | } 168 | &-left { 169 | margin-left: @margin-md; 170 | } 171 | &-right { 172 | margin-right: @margin-md; 173 | } 174 | } 175 | &-lg { 176 | margin: @margin-lg; 177 | &-horizontal { 178 | margin: 0 @margin-lg; 179 | } 180 | &-vertical { 181 | margin: @margin-lg 0; 182 | } 183 | &-top { 184 | margin-top: @margin-lg; 185 | } 186 | &-bottom { 187 | margin-bottom: @margin-lg; 188 | } 189 | &-left { 190 | margin-left: @margin-lg; 191 | } 192 | &-right { 193 | margin-right: @margin-lg; 194 | } 195 | } 196 | } 197 | 198 | // Helpers 199 | // ------------------------- 200 | .data-label { 201 | #fuelux > .data-label(); 202 | } 203 | .data-value { 204 | #fuelux > .data-value(); 205 | } 206 | .section-heading { 207 | #fuelux > .section-heading(); 208 | } 209 | 210 | } --------------------------------------------------------------------------------