├── INSTALL ├── Oliver ├── Oliver │ ├── __init__.py │ ├── __init__.pyc │ ├── settings.py │ ├── settings.pyc │ ├── urls.py │ ├── urls.pyc │ ├── wsgi.py │ └── wsgi.pyc ├── audit │ ├── __init__.py │ ├── __init__.pyc │ ├── views.py │ └── views.pyc ├── cmdb │ ├── __init__.py │ ├── __init__.pyc │ ├── views.py │ └── views.pyc ├── common_static │ ├── img │ │ ├── B24.gif │ │ ├── audit.png │ │ ├── bow.png │ │ ├── home.png │ │ ├── host.png │ │ ├── hostgroupmgr.png │ │ ├── icon-no.gif │ │ ├── icon-yes.gif │ │ ├── login.jpg │ │ ├── moniter.png │ │ ├── query.png │ │ └── ywgl.png │ └── js │ │ ├── chat.js │ │ └── comm.js ├── manage.py ├── static │ ├── admin │ │ ├── css │ │ │ ├── base.css │ │ │ ├── changelists.css │ │ │ ├── dashboard.css │ │ │ ├── forms.css │ │ │ ├── ie.css │ │ │ ├── login.css │ │ │ ├── rtl.css │ │ │ └── widgets.css │ │ ├── img │ │ │ ├── changelist-bg.gif │ │ │ ├── changelist-bg_rtl.gif │ │ │ ├── default-bg-reverse.gif │ │ │ ├── default-bg.gif │ │ │ ├── deleted-overlay.gif │ │ │ ├── gis │ │ │ │ ├── move_vertex_off.png │ │ │ │ └── move_vertex_on.png │ │ │ ├── icon-no.gif │ │ │ ├── icon-unknown.gif │ │ │ ├── icon-yes.gif │ │ │ ├── icon_addlink.gif │ │ │ ├── icon_alert.gif │ │ │ ├── icon_calendar.gif │ │ │ ├── icon_changelink.gif │ │ │ ├── icon_clock.gif │ │ │ ├── icon_deletelink.gif │ │ │ ├── icon_error.gif │ │ │ ├── icon_searchbox.png │ │ │ ├── icon_success.gif │ │ │ ├── inline-delete-8bit.png │ │ │ ├── inline-delete.png │ │ │ ├── inline-restore-8bit.png │ │ │ ├── inline-restore.png │ │ │ ├── inline-splitter-bg.gif │ │ │ ├── nav-bg-grabber.gif │ │ │ ├── nav-bg-reverse.gif │ │ │ ├── nav-bg-selected.gif │ │ │ ├── nav-bg.gif │ │ │ ├── selector-icons.gif │ │ │ ├── selector-search.gif │ │ │ ├── sorting-icons.gif │ │ │ ├── tooltag-add.png │ │ │ └── tooltag-arrowright.png │ │ └── js │ │ │ ├── LICENSE-JQUERY.txt │ │ │ ├── SelectBox.js │ │ │ ├── SelectFilter2.js │ │ │ ├── actions.js │ │ │ ├── actions.min.js │ │ │ ├── admin │ │ │ ├── DateTimeShortcuts.js │ │ │ └── RelatedObjectLookups.js │ │ │ ├── calendar.js │ │ │ ├── collapse.js │ │ │ ├── collapse.min.js │ │ │ ├── core.js │ │ │ ├── inlines.js │ │ │ ├── inlines.min.js │ │ │ ├── jquery.init.js │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ ├── prepopulate.js │ │ │ ├── prepopulate.min.js │ │ │ ├── related-widget-wrapper.js │ │ │ ├── timeparse.js │ │ │ └── urlify.js │ ├── img │ │ ├── B24.gif │ │ ├── audit.png │ │ ├── bow.png │ │ ├── home.png │ │ ├── host.png │ │ ├── hostgroupmgr.png │ │ ├── icon-no.gif │ │ ├── icon-yes.gif │ │ ├── login.jpg │ │ ├── moniter.png │ │ ├── query.png │ │ └── ywgl.png │ └── js │ │ ├── chat.js │ │ └── comm.js ├── statistics │ ├── __init__.py │ ├── __init__.pyc │ ├── views.py │ ├── views.py.eri │ └── views.pyc ├── templates │ ├── bstrap.html │ ├── index.html │ ├── left-menu.20160415.html │ ├── left-menu.html │ ├── nav.20160415.html │ ├── nav.html │ ├── test.html │ ├── top-icon.html │ └── ywweb │ │ ├── addhostgroup.html │ │ ├── addmodule.html │ │ ├── addserver.html │ │ ├── addweb.html │ │ ├── audit.html │ │ ├── edithostgroup.html │ │ ├── editserver.html │ │ ├── editweb.html │ │ ├── hostgroup.html │ │ ├── modal.html │ │ ├── query.html │ │ ├── server_detail.html │ │ ├── server_info.html │ │ ├── web.html │ │ └── ywgl.html ├── uwsgi.ini ├── webapi │ ├── __init__.py │ ├── __init__.pyc │ ├── insertdata.py │ ├── insertdata.pyc │ ├── libraries.py │ ├── libraries.pyc │ ├── sniffer.py │ └── sniffer.pyc ├── webmoniter │ ├── __init__.py │ ├── __init__.pyc │ ├── views.py │ ├── views.py.eri │ └── views.pyc ├── ywgl │ ├── __init__.py │ ├── __init__.pyc │ ├── views.py │ └── views.pyc └── ywmodels │ ├── __init__.py │ ├── __init__.pyc │ ├── admin.py │ ├── admin.pyc │ ├── migrations │ ├── 0001_initial.py │ ├── 0001_initial.pyc │ ├── __init__.py │ └── __init__.pyc │ ├── models.py │ └── models.pyc ├── OliverAudit ├── OliverAudit_agent.py ├── config.py ├── config.pyc └── omsys.log ├── OliverServer ├── OliverServer.py ├── config.py ├── config.pyc ├── libraries.py ├── libraries.pyc ├── logs │ └── omsys.log └── modules │ └── ansible │ ├── Mid_1001.py │ ├── Mid_1001.pyc │ ├── Mid_1002.py │ ├── Mid_1002.pyc │ ├── Mid_1003.py │ ├── Mid_1003.pyc │ ├── Mid_1004.py │ ├── Mid_1004.pyc │ ├── Mid_1005.py │ ├── Mid_1005.pyc │ ├── Mid_1006.py │ ├── Mid_1006.pyc │ ├── Mid_1007.py │ ├── Mid_1007.pyc │ ├── Mid_1008.py │ ├── Mid_1008.pyc │ ├── Mid_1009.py │ ├── Mid_1009.pyc │ ├── Mid_1010.py │ ├── Mid_1010.pyc │ ├── Public_lib.py │ ├── Public_lib.pyc │ └── __init__.py ├── README.md ├── cmdb.sql ├── nginx.conf └── supervisord.conf /INSTALL: -------------------------------------------------------------------------------- 1 | Oliver运维管理系统安装部署 2 | 3 | 1、安装以下软件 4 | 1.1 安装nginx 5 | 安装过程略 6 | 7 | 1.2 安装mysql 8 | 安装过程略 9 | 10 | 1.3 安装python2.7.10 11 | 升级安装python2.7.10 12 | wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz 13 | tar -zxf Python-2.7.10.tgz 14 | cd Python-2.7.10 15 | ./configure 16 | make all 17 | make install 18 | make clean 19 | make distclean 20 | 21 | 查看版本 22 | /usr/local/bin/python2.7 -V 23 | 24 | 建议软链接 25 | mv /usr/bin/python /usr/bin/python2.6.6 26 | ln -s /usr/local/bin/python2.7 /usr/bin/python 27 | 28 | 重新验证版本 29 | python -V 30 | 31 | 1.4 安装setuptools 32 | wget https://pypi.python.org/packages/source/s/setuptools/setuptools-19.2.tar.gz 33 | tar -zxf setuptools-19.2.tar.gz 34 | cd setuptools-19.2 35 | python setup.py install 36 | 37 | 1.5 安装pip8.1.1 38 | wget https://pypi.python.org/packages/source/p/pip/pip-8.1.1.tar.gz 39 | tar -zxf pip-8.1.1.tar.gz 40 | cd pip-8.1.1 41 | python setup.py install 42 | 43 | 2、关闭selinux并开放iptables的80端口 44 | setenforce 0 45 | sed -i '/^SELINUX=/{s/enforcing/disabled/}' /etc/sysconfig/selinux 46 | sed -i '/^SELINUX=/{s/enforcing/disabled/}' /etc/selinux/config 47 | iptables -I INPUT 4 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT 48 | /etc/init.d/iptables save 49 | 50 | 3、pip安装如下包 51 | pip install supervisor 52 | pip install uwsgi 53 | pip install ansible==1.9.4 54 | pip install Django==1.8.3 55 | pip install django-users2 56 | pip install MySQL-python 57 | pip install rpyc 58 | 59 | 4、创建uwsgi.ini 60 | 建议放置在项目所在目录下 61 | [uwsgi] 62 | socket = /tmp/oliver.sock #nginx需要使用到的socket文件 63 | chdir=/opt/www/oliver #切换到项目所在目录 64 | wsgi-file = Oliver/wsgi.py #wsgi.py主程序入口,加载相应环境 65 | touch-reload=/opt/www/oliver/reload #touch一个空白的reload文件,项目重启 66 | processes = 2 #初始启动进程数 67 | threads = 4 68 | chmod-socket = 664 #socket文件的属性 69 | chown-socket = nginx:nginx #socket文件的属主和属组 70 | 71 | 5、创建supervisor配置文件 72 | echo_supervisord_conf > /etc/supervisord.conf 73 | 74 | 6、编辑supervisor配置文件 75 | 在/etc/supervisord.conf末尾追加 76 | [program:oliver] #oliver是supervisor管理的进程名 77 | command=/usr/local/bin/uwsgi --ini /www/oliver/uwsgi.ini 78 | directory=/www/oliver 79 | startsecs=0 80 | stopwaitsecs=0 81 | autostart=true 82 | autorestart=true 83 | 84 | 7、启动supervisor 85 | supervisord -c /etc/supervisord.conf 86 | 查看/tmp/oliver.sock文件是否存在,如果不存在可先将/tmp目录下文件删除,然后再一次执行上面的命令 87 | 88 | supervisor管理进程命令: 89 | 停止进程: 90 | supervisorctl -c /etc/supervisord.conf stop oliver 91 | 92 | 启动进程: 93 | supervisorctl -c /etc/supervisord.conf start oliver 94 | 95 | 重启进程: 96 | supervisorctl -c /etc/supervisord.conf restart oliver 97 | 98 | 8、修改nginx配置 99 | nginx的配置文件中添加虚拟主机配置: 100 | server { 101 | listen 80; 102 | server_name localhost; 103 | charset utf-8; 104 | client_max_body_size 8M; 105 | location /media { 106 | alias /opt/www/Oliver/media; 107 | } 108 | location /static { 109 | alias /opt/www/Oliver/static; 110 | } 111 | location / { 112 | uwsgi_pass unix:///tmp/oliver.sock; 113 | include /opt/application/nginx/conf/uwsgi_params; 114 | } 115 | } 116 | 117 | django仅在开发模式可加载setting.py配置中指定目录下的静态文件,在生产环境要通过nginx配置来加载静态文件,创建static和media目录。 118 | 119 | 9、添加网站监控脚本到定时任务 120 | */5 * * * * /usr/local/bin/python /opt/www/Oliver/webapi/sniffer.py >/dev/null 2>&1 121 | 122 | 10、在需要做安全审计的主机的/etc/profile文件中添加如下配置 123 | HISTSIZE=1200 124 | export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE 125 | export HISTCONTROL=ignoredups 126 | export HISTFILE=$HOME/.bash_history 127 | export HISTFILESIZE=1200 128 | export HISTTIMEFORMAT="`whoami` %F %T " 129 | export PROMPT_COMMAND="history -a; history -c; history -r;"'/opt/www/OMAudit/OMAudit_agent.py $(history 1)' 130 | shopt -s histappend 131 | typeset -r PROMPT_COMMAND 132 | typeset -r HISTTIMEFORMAT 133 | 134 | 11、搜集静态文件到指定目录 135 | 在setting.py中配置STATIC_ROOT来指定搜集静态文件存放目录: 136 | python manage.py collectstatic 137 | 每次修改静态文件内容,也需要执行一次以上命令,否则修改后的内容nginx加载不到 138 | 139 | 12、同步数据库 140 | python manage.py makemigrations 141 | python manage.py migrate 142 | 143 | 13、启动OliverServer主进程 144 | python OliverServer.py & 145 | 146 | 13、重启nginx和supervisor 147 | service nginx restart 148 | supervisorctl -c /etc/supervisord.conf restart oliver 149 | -------------------------------------------------------------------------------- /Oliver/Oliver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/Oliver/__init__.py -------------------------------------------------------------------------------- /Oliver/Oliver/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/Oliver/__init__.pyc -------------------------------------------------------------------------------- /Oliver/Oliver/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for cmdb project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.8/ref/settings/ 11 | """ 12 | 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 14 | import os 15 | import Oliver 16 | from django.conf.global_settings import STATIC_ROOT, STATICFILES_DIRS 17 | 18 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 19 | 20 | 21 | # Quick-start development settings - unsuitable for production 22 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 23 | 24 | # SECURITY WARNING: keep the secret key used in production secret! 25 | SECRET_KEY = '*b$%+mw52yw0_psgevus^m%hjl+!+3l+hgt!2^_okl2c9r)q=a' 26 | 27 | # SECURITY WARNING: don't run with debug turned on in production! 28 | DEBUG = False 29 | 30 | ALLOWED_HOSTS = ['*'] 31 | 32 | 33 | # Application definition 34 | 35 | INSTALLED_APPS = ( 36 | 'django.contrib.admin', 37 | 'django.contrib.auth', 38 | 'django.contrib.contenttypes', 39 | 'django.contrib.sessions', 40 | 'django.contrib.messages', 41 | 'django.contrib.staticfiles', 42 | 'ywmodels', 43 | 'cmdb', 44 | 'audit', 45 | 'ywgl', 46 | 'webmoniter', 47 | 'users', 48 | ) 49 | 50 | AUTH_USER_MODEL = 'users.User' 51 | LOGIN_REDIRECT_URL = '/' 52 | 53 | MIDDLEWARE_CLASSES = ( 54 | 'django.contrib.sessions.middleware.SessionMiddleware', 55 | 'django.middleware.common.CommonMiddleware', 56 | 'django.middleware.csrf.CsrfViewMiddleware', 57 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 58 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 59 | 'django.contrib.messages.middleware.MessageMiddleware', 60 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 61 | 'django.middleware.security.SecurityMiddleware', 62 | ) 63 | 64 | ROOT_URLCONF = 'Oliver.urls' 65 | 66 | TEMPLATES = [ 67 | { 68 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 69 | 'DIRS': [os.path.join(BASE_DIR, 'templates')], 70 | 'APP_DIRS': True, 71 | 'OPTIONS': { 72 | 'context_processors': [ 73 | 'django.template.context_processors.debug', 74 | 'django.template.context_processors.request', 75 | 'django.contrib.auth.context_processors.auth', 76 | 'django.contrib.messages.context_processors.messages', 77 | ], 78 | }, 79 | }, 80 | ] 81 | 82 | WSGI_APPLICATION = 'Oliver.wsgi.application' 83 | 84 | 85 | # Database 86 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 87 | 88 | DATABASES = { 89 | 'default': { 90 | 'ENGINE': 'django.db.backends.mysql', 91 | 'NAME': 'cmdb', 92 | 'PORT': '3307', 93 | 'HOST': 'localhost', 94 | 'USER': 'oliver', 95 | 'PASSWORD': 'WF#@&tu87wr45', 96 | } 97 | } 98 | 99 | 100 | # Internationalization 101 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 102 | 103 | LANGUAGE_CODE = 'en-us' 104 | 105 | TIME_ZONE = 'Asia/Shanghai' 106 | 107 | USE_I18N = True 108 | 109 | USE_L10N = True 110 | 111 | USE_TZ = False 112 | 113 | 114 | # Static files (CSS, JavaScript, Images) 115 | # https://docs.djangoproject.com/en/1.8/howto/static-files/ 116 | 117 | STATIC_URL = '/static/' 118 | STATIC_ROOT = os.path.join(BASE_DIR, 'static') 119 | STATICFILES_DIRS = ( 120 | os.path.join(BASE_DIR, 'common_static'), 121 | ) 122 | 123 | #login and register configuration 124 | USERS_REGISTRATION_OPEN = False 125 | 126 | USERS_VERIFY_EMAIL = False 127 | 128 | USERS_AUTO_LOGIN_ON_ACTIVATION = False 129 | 130 | USERS_EMAIL_CONFIRMATION_TIMEOUT_DAYS = 3 131 | 132 | # Specifies minimum length for passwords: 133 | USERS_PASSWORD_MIN_LENGTH = 5 134 | 135 | # Specifies maximum length for passwords: 136 | USERS_PASSWORD_MAX_LENGTH = None 137 | 138 | # the complexity validator, checks the password strength 139 | USERS_CHECK_PASSWORD_COMPLEXITY = True 140 | 141 | USERS_SPAM_PROTECTION = False # important! 142 | 143 | 144 | # --------------------------------------------------------- 145 | # # Email 146 | # EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 147 | # 148 | # EMAIL_USE_TLS = False 149 | # EMAIL_HOST = 'smtp.163.com' 150 | # EMAIL_PORT = 25 151 | # EMAIL_HOST_USER = 'mail@test.com' 152 | # EMAIL_HOST_PASSWORD = 'xxxx' 153 | # DEFAULT_FROM_EMAIL = 'mail@test.com' 154 | # # --------------------------------------------------------- 155 | -------------------------------------------------------------------------------- /Oliver/Oliver/settings.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/Oliver/settings.pyc -------------------------------------------------------------------------------- /Oliver/Oliver/urls.py: -------------------------------------------------------------------------------- 1 | """cmdb URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.conf.urls import include, url 17 | from django.contrib import admin 18 | from cmdb.views import * 19 | from audit.views import * 20 | from ywgl.views import * 21 | from webmoniter.views import * 22 | from statistics.views import * 23 | 24 | urlpatterns = [ 25 | # url(r'^admin/', include(admin.site.urls)), 26 | url(r'^accounts/', include('users.urls')), 27 | url(r'^$', index, name='index'), 28 | url(r'^index/(?P[^/]+)/$', mychat, name='mychat'), 29 | url(r'^server_group/(?P\d+)?', server_group, name='server_group'), 30 | url(r'^server_group_edit/(?P\d+)/$', server_group_edit, name='server_group_edit'), 31 | url(r'^server/(?P\d+)?', server_info, name='server_info'), 32 | url(r'^server_detail/(?P\d+)/(?P[^/]+)/$', server_detail, name='server_detail'), 33 | url(r'^server_edit/(?P\d+)/$', server_edit, name='server_edit'), 34 | url(r'^web/(?P\d+)?', web, name='web'), 35 | url(r'^web_edit/(?P\d+)/$', web_edit, name='web_edit'), 36 | url(r'^add/(?P[^/]+)/$', add, name='add'), 37 | url(r'^delete/(?P[^/]+)/$', delete, name='delete'), 38 | url(r'^ywgl/$', ywgl, name='ywgl'), 39 | url(r'^ywgl/displaymem/$', displaymem), 40 | url(r'^ywgl/displayfunc/$', displayfunc), 41 | url(r'^ywgl/addmodule/$', addmodule, name='addmodule'), 42 | url(r'^ywgl/handlemodule/$', handlemodule, name='handlemodule'), 43 | url(r'^audit/$', audit, name='audit'), 44 | url(r'^audit/audit_pull/$', audit_pull, name='audit_pull'), 45 | url(r'^audit/audit_run/$', audit_run, name='audit_run'), 46 | url(r'^audit/audit_host/$', audit_host, name='audit_host'), 47 | url(r'^audit/audit_sjquery/$', audit_sjquery, name='audit_sjquery'), 48 | url(r'^query/$', query, name='query'), 49 | url(r'^query2/$', query2, name='query2'), 50 | ] 51 | -------------------------------------------------------------------------------- /Oliver/Oliver/urls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/Oliver/urls.pyc -------------------------------------------------------------------------------- /Oliver/Oliver/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for Oliver 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.8/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Oliver.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Oliver/Oliver/wsgi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/Oliver/wsgi.pyc -------------------------------------------------------------------------------- /Oliver/audit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/audit/__init__.py -------------------------------------------------------------------------------- /Oliver/audit/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/audit/__init__.pyc -------------------------------------------------------------------------------- /Oliver/audit/views.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from django.shortcuts import render 3 | from django.http.response import HttpResponse 4 | from ywmodels.models import ServerHistory, Hostgroup 5 | import datetime 6 | from django.contrib.auth.decorators import login_required 7 | 8 | # Create your views here. 9 | @login_required 10 | def audit(request): 11 | hostgroup = Hostgroup.objects.all() 12 | return render(request, 'ywweb/audit.html', {'hostgroup': hostgroup}) 13 | 14 | @login_required 15 | def audit_host(request): 16 | grouplist = [] 17 | memstr = "" 18 | if request.GET: 19 | grouplist = request.GET.get('gpnames').strip('@@').split('@@') 20 | for group in grouplist: 21 | groupobj = Hostgroup.objects.get(name=group) 22 | for mem in groupobj.member.split(','): 23 | memstr += '' 24 | return HttpResponse(memstr) 25 | 26 | @login_required 27 | def audit_run(request): 28 | 29 | LastID = request.GET.get('LastID', '') 30 | Hosts = request.GET.get('Hosts', '') 31 | ServerHistory_string="" 32 | host_array=Hosts.strip("@@").split("@@") 33 | if LastID=="0": 34 | if Hosts=="": 35 | ServerHistoryObj = ServerHistory.objects.order_by('-id')[:5] 36 | else: 37 | ServerHistoryObj = ServerHistory.objects \ 38 | .filter(history_ip__in=host_array).order_by('-id')[:5] 39 | else: 40 | if Hosts=="": 41 | ServerHistoryObj = ServerHistory.objects.filter(id__gt=LastID).order_by('-id') 42 | # print ServerHistoryObj 43 | else: 44 | ServerHistoryObj = ServerHistory.objects \ 45 | .filter(id__gt=LastID,history_ip__in=host_array).order_by('-id') 46 | 47 | if ServerHistoryObj: 48 | lastid="" 49 | i=0 50 | for e in ServerHistoryObj: 51 | if i==0: 52 | lastid=e.id 53 | ServerHistory_string+=""+e.history_ip+"  \t"+\ 54 | e.history_user+"  \t"+str(e.db_datetime)+"  \t"+e.history_command+"*"+"
" 55 | i+=1 56 | else: 57 | lastid=LastID 58 | ServerHistory_string+="@@"+str(lastid) 59 | return HttpResponse(ServerHistory_string) 60 | 61 | """ 62 | =事件任务pull方法 63 | """ 64 | 65 | def audit_pull(request): 66 | if request.method == 'GET': 67 | if not request.GET.get('history_id', ''): 68 | return HttpResponse("history_id null") 69 | 70 | if not request.GET.get('history_ip', ''): 71 | return HttpResponse("history_ip null") 72 | 73 | if not request.GET.get('history_user', ''): 74 | return HttpResponse("history_user null") 75 | 76 | if not request.GET.get('history_datetime', ''): 77 | return HttpResponse("history_datetime null") 78 | 79 | if not request.GET.get('history_command', ''): 80 | return HttpResponse("history_command null") 81 | 82 | history_id=request.GET['history_id'] 83 | history_ip=request.GET['history_ip'] 84 | history_user=request.GET['history_user'] 85 | history_datetime=request.GET['history_datetime'] 86 | history_command=request.GET['history_command'] 87 | 88 | historyobj = ServerHistory(history_id=history_id, \ 89 | history_ip=history_ip, \ 90 | history_user=history_user, \ 91 | history_datetime=history_datetime, \ 92 | history_command=history_command) 93 | try: 94 | historyobj.save() 95 | except Exception,e: 96 | return HttpResponse("入库失败,请与管理员联系!"+str(e)) 97 | 98 | Response_result="OK" 99 | return HttpResponse(Response_result) 100 | 101 | else: 102 | return HttpResponse("非法提交!") 103 | 104 | @login_required 105 | def audit_sjquery(request): 106 | ServerHistory_string = "" 107 | sjdate = request.GET['sjdate'].replace('T',' ') 108 | curDate = datetime.datetime.strptime(sjdate, "%Y-%m-%d %H:%M") 109 | histobjs = ServerHistory.objects.filter(db_datetime__gt=curDate) 110 | for e in histobjs: 111 | ServerHistory_string+=""+e.history_ip+"  \t"+\ 112 | e.history_user+"  \t"+str(e.db_datetime)+"  \t"+e.history_command+"*"+"
" 113 | return HttpResponse(ServerHistory_string) 114 | -------------------------------------------------------------------------------- /Oliver/audit/views.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/audit/views.pyc -------------------------------------------------------------------------------- /Oliver/cmdb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/cmdb/__init__.py -------------------------------------------------------------------------------- /Oliver/cmdb/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/cmdb/__init__.pyc -------------------------------------------------------------------------------- /Oliver/cmdb/views.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from __future__ import unicode_literals 3 | from django.shortcuts import render, redirect 4 | from ywmodels.models import * 5 | from django.http.response import HttpResponse 6 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 7 | from webapi.insertdata import insertdata 8 | import json, datetime, math 9 | from django.db.models import Q 10 | from django.contrib.auth.decorators import login_required 11 | 12 | # Create your views here. 13 | 14 | 15 | def index(request): 16 | return render(request, 'index.html') 17 | 18 | def mychat(request, catalog): 19 | if catalog == "server_cata": 20 | ret = {"physerver": 0, "vmserver": 0, "esxiserver": 0, "networkdevice": 0,} 21 | ret["physerver"] = Server.objects.filter(device_type="物理服务器").count() 22 | ret["vmserver"] = Server.objects.filter(device_type="虚拟服务器").count() 23 | ret["esxiserver"] = Server.objects.filter(device_type="ESXi服务器").count() 24 | ret["networkdevice"] = Server.objects.filter(device_type="网络设备").count() 25 | serCata = json.dumps(ret) 26 | return HttpResponse(serCata) 27 | if catalog == "platpt": 28 | ret = {"yhypt": 0, "ydrpt": 0, "xppt": 0, "drpt": 0, "glpt": 0, "yxpt": 0, "other": 0} 29 | ptlist = ['医患药平台', '药店人平台', '西普平台', 'DR数据平台', '管理平台', '营销平台', '其它'] 30 | res = [] 31 | for pt in ptlist: 32 | ptobj = BusinessUnit.objects.get(name=pt) 33 | num = ptobj.server_set.all().count() 34 | res.append(num) 35 | ret["yhypt"] = res[0] 36 | ret["ydrpt"] = res[1] 37 | ret["xppt"] = res[2] 38 | ret["drpt"] = res[3] 39 | ret["glpt"] = res[4] 40 | ret["yxpt"] = res[5] 41 | ret["other"] = res[6] 42 | platjs = json.dumps(ret) 43 | return HttpResponse(platjs) 44 | if catalog == "usestatus": 45 | ret = {"online": 0, "offline": 0} 46 | ret["online"] = Server.objects.filter(status="online").count() 47 | ret["offline"] = Server.objects.filter(status="offline").count() 48 | usestatus = json.dumps(ret) 49 | return HttpResponse(usestatus) 50 | if catalog == "maintenance": 51 | ret = {"inner": 0, "outer": 0} 52 | now = datetime.datetime.now() 53 | ret["inner"] = Server.objects.filter(~Q(sn="")).filter(service_time__gt=now).count() 54 | ret["outer"] = Server.objects.filter(~Q(sn="")).filter(service_time__lt=now).count() 55 | maintenance = json.dumps(ret) 56 | return HttpResponse(maintenance) 57 | 58 | @login_required 59 | def server_info(request, pk): 60 | if request.method == "GET": 61 | server_objs = Server.objects.all().order_by('id') 62 | if request.method == "POST": 63 | server_list = [] 64 | try: 65 | insertdata(request, pk) #如果是POST请求,先插入数据 66 | except Exception,e: 67 | return HttpResponse("插入数据失败,请与管理员联系"+str(e)) 68 | server_objs = Server.objects.all().order_by('id') 69 | server_list = list(server_objs) 70 | paginator = Paginator(server_objs, 8) 71 | #如果pk存在则是修改,pk不存在则是添加server 72 | if pk: 73 | pkobj = Server.objects.get(id=pk) 74 | server_pos = server_list.index(pkobj) 75 | page = (server_pos+1) / 8.0 76 | page = int(math.ceil(page)) 77 | servers = paginator.page(page) 78 | else: 79 | page = server_objs.count() / 8.0 80 | page = int(math.ceil(page)) 81 | servers = paginator.page(page) 82 | return render(request, 'ywweb/server_info.html', {'servers': servers}) 83 | paginator = Paginator(server_objs, 8) 84 | try: 85 | page = request.GET.get('page') 86 | servers = paginator.page(page) 87 | except PageNotAnInteger: 88 | # If page is not an integer, deliver first page. 89 | servers = paginator.page(1) 90 | except EmptyPage: 91 | # If page is out of range (e.g. 9999), deliver last page of results. 92 | servers = paginator.page(paginator.num_pages) 93 | 94 | return render(request, 'ywweb/server_info.html', {'servers': servers}) 95 | 96 | @login_required 97 | def server_detail(request, pk, sn): 98 | serobj = Server.objects.get(id=pk) 99 | return render(request, 'ywweb/server_detail.html', {'serobj': serobj}) 100 | 101 | 102 | #对监控站点,主机与主机组执行添加操作返回的页面 103 | @login_required 104 | def add(request, service): 105 | if service == "web": 106 | return render(request, 'ywweb/addweb.html') 107 | elif service == "host": 108 | return render(request, 'ywweb/addserver.html') 109 | elif service == "hostgroup": 110 | groups = Hostgroup.objects.all() 111 | servers = Server.objects.all().exclude(hostgroup__in=groups) #排除存在于主机组当中的所有主机 112 | return render(request, 'ywweb/addhostgroup.html', {'servers': servers}) 113 | else: 114 | return redirect('/server/') 115 | 116 | #对主机或监控站点执行删除操作 117 | @login_required 118 | def delete(request, content): 119 | pkstr = request.GET.get('pk', None) 120 | if pkstr: 121 | pklist = pkstr.strip(',').split(',') 122 | if content == 'host': 123 | for pk in pklist: 124 | server = Server.objects.get(id=pk) 125 | #先删除hostgroup中的管理IP 126 | if server.hostgroup: 127 | mip = server.ipaddr_set.all().get(ip_type='管理IP') 128 | mlist = server.hostgroup.member.split(',') 129 | mlist.remove(mip.address) 130 | server.hostgroup.member = ','.join(mlist) 131 | server.hostgroup.save() 132 | server.delete() 133 | if content == "web": 134 | for pk in pklist: 135 | site = Websniff.objects.get(id=pk) 136 | site.delete() 137 | return HttpResponse("ok") 138 | else: 139 | return HttpResponse("请确认已选择项目") 140 | 141 | @login_required 142 | def server_edit(request, pk): 143 | server = Server.objects.get(id=pk) 144 | curdate = datetime.date.strftime(server.service_time, format='%Y-%m-%d') 145 | return render(request, 'ywweb/editserver.html', {'server': server, 'curdate': curdate}) 146 | 147 | @login_required 148 | def server_group_edit(request, pk): 149 | hostgroup = Hostgroup.objects.get(id=pk) 150 | groups = Hostgroup.objects.all() 151 | servers = Server.objects.all().exclude(hostgroup__in=groups) #排除存在于主机组当中的所有主机 152 | return render(request, 'ywweb/edithostgroup.html', {'hostgroup': hostgroup, 'servers': servers}) 153 | 154 | #减少时如何处理 155 | @login_required 156 | def server_group(request, pk): 157 | if request.method == "POST": 158 | iplist = [] 159 | groupname = request.POST.get('groupname', None) 160 | groupmember_2 = request.POST.getlist('groupmember_2') 161 | 162 | if pk: 163 | group = Hostgroup.objects.get(id=pk) 164 | group.name = groupname 165 | if group.member: 166 | iplist = group.member.split(',') 167 | if len(groupmember_2) < len(iplist): 168 | crossiplist = list(set(iplist) - set(groupmember_2)) #获得哪些主机需要删除组对象 169 | for mangip in crossiplist: 170 | ipobjs = Ipaddr.objects.get(ip_type='管理IP', address=mangip) 171 | server = ipobjs.server_info 172 | server.hostgroup = None 173 | server.save() 174 | else: 175 | group = Hostgroup.objects.get_or_create(name=groupname)[0] #创建一个新的主机组 176 | memstr = ','.join(groupmember_2) 177 | group.member = memstr 178 | group.save() 179 | if groupmember_2: 180 | for mangip in groupmember_2: 181 | ipobj = Ipaddr.objects.get(ip_type='管理IP', address=mangip) #先创建管理IP的ip对象 182 | server = ipobj.server_info 183 | server.hostgroup = group 184 | server.save() 185 | hostgroup = Hostgroup.objects.all() 186 | return render(request, 'ywweb/hostgroup.html', {'hostgroup': hostgroup}) 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /Oliver/cmdb/views.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/cmdb/views.pyc -------------------------------------------------------------------------------- /Oliver/common_static/img/B24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/B24.gif -------------------------------------------------------------------------------- /Oliver/common_static/img/audit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/audit.png -------------------------------------------------------------------------------- /Oliver/common_static/img/bow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/bow.png -------------------------------------------------------------------------------- /Oliver/common_static/img/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/home.png -------------------------------------------------------------------------------- /Oliver/common_static/img/host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/host.png -------------------------------------------------------------------------------- /Oliver/common_static/img/hostgroupmgr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/hostgroupmgr.png -------------------------------------------------------------------------------- /Oliver/common_static/img/icon-no.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/icon-no.gif -------------------------------------------------------------------------------- /Oliver/common_static/img/icon-yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/icon-yes.gif -------------------------------------------------------------------------------- /Oliver/common_static/img/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/login.jpg -------------------------------------------------------------------------------- /Oliver/common_static/img/moniter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/moniter.png -------------------------------------------------------------------------------- /Oliver/common_static/img/query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/query.png -------------------------------------------------------------------------------- /Oliver/common_static/img/ywgl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/common_static/img/ywgl.png -------------------------------------------------------------------------------- /Oliver/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", "Oliver.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /Oliver/static/admin/css/changelists.css: -------------------------------------------------------------------------------- 1 | /* CHANGELISTS */ 2 | 3 | #changelist { 4 | position: relative; 5 | width: 100%; 6 | } 7 | 8 | #changelist table { 9 | width: 100%; 10 | } 11 | 12 | .change-list .hiddenfields { display:none; } 13 | 14 | .change-list .filtered table { 15 | border-right: 1px solid #ddd; 16 | } 17 | 18 | .change-list .filtered { 19 | min-height: 400px; 20 | } 21 | 22 | .change-list .filtered { 23 | background: white url(../img/changelist-bg.gif) top right repeat-y !important; 24 | } 25 | 26 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 27 | margin-right: 160px !important; 28 | width: auto !important; 29 | } 30 | 31 | .change-list .filtered table tbody th { 32 | padding-right: 1em; 33 | } 34 | 35 | #changelist-form .results { 36 | overflow-x: auto; 37 | } 38 | 39 | #changelist .toplinks { 40 | border-bottom: 1px solid #ccc !important; 41 | } 42 | 43 | #changelist .paginator { 44 | color: #666; 45 | border-top: 1px solid #eee; 46 | border-bottom: 1px solid #eee; 47 | background: white url(../img/nav-bg.gif) 0 180% repeat-x; 48 | overflow: hidden; 49 | } 50 | 51 | .change-list .filtered .paginator { 52 | border-right: 1px solid #ddd; 53 | } 54 | 55 | /* CHANGELIST TABLES */ 56 | 57 | #changelist table thead th { 58 | padding: 0; 59 | white-space: nowrap; 60 | vertical-align: middle; 61 | } 62 | 63 | #changelist table thead th.action-checkbox-column { 64 | width: 1.5em; 65 | text-align: center; 66 | } 67 | 68 | #changelist table tbody td, #changelist table tbody th { 69 | border-left: 1px solid #ddd; 70 | } 71 | 72 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 73 | border-left: 0; 74 | border-right: 1px solid #ddd; 75 | } 76 | 77 | #changelist table tbody td.action-checkbox { 78 | text-align:center; 79 | } 80 | 81 | #changelist table tfoot { 82 | color: #666; 83 | } 84 | 85 | /* TOOLBAR */ 86 | 87 | #changelist #toolbar { 88 | padding: 3px; 89 | border-bottom: 1px solid #ddd; 90 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 91 | color: #666; 92 | } 93 | 94 | #changelist #toolbar form input { 95 | font-size: 11px; 96 | padding: 1px 2px; 97 | } 98 | 99 | #changelist #toolbar form #searchbar { 100 | padding: 2px; 101 | } 102 | 103 | #changelist #changelist-search img { 104 | vertical-align: middle; 105 | } 106 | 107 | /* FILTER COLUMN */ 108 | 109 | #changelist-filter { 110 | position: absolute; 111 | top: 0; 112 | right: 0; 113 | z-index: 1000; 114 | width: 160px; 115 | border-left: 1px solid #ddd; 116 | background: #efefef; 117 | margin: 0; 118 | } 119 | 120 | #changelist-filter h2 { 121 | font-size: 11px; 122 | padding: 2px 5px; 123 | border-bottom: 1px solid #ddd; 124 | } 125 | 126 | #changelist-filter h3 { 127 | font-size: 12px; 128 | margin-bottom: 0; 129 | } 130 | 131 | #changelist-filter ul { 132 | padding-left: 0; 133 | margin-left: 10px; 134 | } 135 | 136 | #changelist-filter li { 137 | list-style-type: none; 138 | margin-left: 0; 139 | padding-left: 0; 140 | } 141 | 142 | #changelist-filter a { 143 | color: #999; 144 | } 145 | 146 | #changelist-filter a:hover { 147 | color: #036; 148 | } 149 | 150 | #changelist-filter li.selected { 151 | border-left: 5px solid #ccc; 152 | padding-left: 5px; 153 | margin-left: -10px; 154 | } 155 | 156 | #changelist-filter li.selected a { 157 | color: #5b80b2 !important; 158 | } 159 | 160 | /* DATE DRILLDOWN */ 161 | 162 | .change-list ul.toplinks { 163 | display: block; 164 | background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; 165 | border-top: 1px solid white; 166 | float: left; 167 | padding: 0 !important; 168 | margin: 0 !important; 169 | width: 100%; 170 | } 171 | 172 | .change-list ul.toplinks li { 173 | padding: 3px 6px; 174 | font-weight: bold; 175 | list-style-type: none; 176 | display: inline-block; 177 | } 178 | 179 | .change-list ul.toplinks .date-back a { 180 | color: #999; 181 | } 182 | 183 | .change-list ul.toplinks .date-back a:hover { 184 | color: #036; 185 | } 186 | 187 | /* PAGINATOR */ 188 | 189 | .paginator { 190 | font-size: 11px; 191 | padding-top: 10px; 192 | padding-bottom: 10px; 193 | line-height: 22px; 194 | margin: 0; 195 | border-top: 1px solid #ddd; 196 | } 197 | 198 | .paginator a:link, .paginator a:visited { 199 | padding: 2px 6px; 200 | border: solid 1px #ccc; 201 | background: white; 202 | text-decoration: none; 203 | } 204 | 205 | .paginator a.showall { 206 | padding: 0 !important; 207 | border: none !important; 208 | } 209 | 210 | .paginator a.showall:hover { 211 | color: #036 !important; 212 | background: transparent !important; 213 | } 214 | 215 | .paginator .end { 216 | border-width: 2px !important; 217 | margin-right: 6px; 218 | } 219 | 220 | .paginator .this-page { 221 | padding: 2px 6px; 222 | font-weight: bold; 223 | font-size: 13px; 224 | vertical-align: top; 225 | } 226 | 227 | .paginator a:hover { 228 | color: white; 229 | background: #5b80b2; 230 | border-color: #036; 231 | } 232 | 233 | /* ACTIONS */ 234 | 235 | .filtered .actions { 236 | margin-right: 160px !important; 237 | border-right: 1px solid #ddd; 238 | } 239 | 240 | #changelist table input { 241 | margin: 0; 242 | } 243 | 244 | #changelist table tbody tr.selected { 245 | background-color: #FFFFCC; 246 | } 247 | 248 | #changelist .actions { 249 | color: #999; 250 | padding: 3px; 251 | border-top: 1px solid #fff; 252 | border-bottom: 1px solid #ddd; 253 | background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; 254 | } 255 | 256 | #changelist .actions.selected { 257 | background: #fffccf; 258 | border-top: 1px solid #fffee8; 259 | border-bottom: 1px solid #edecd6; 260 | } 261 | 262 | #changelist .actions span.all, 263 | #changelist .actions span.action-counter, 264 | #changelist .actions span.clear, 265 | #changelist .actions span.question { 266 | font-size: 11px; 267 | margin: 0 0.5em; 268 | display: none; 269 | } 270 | 271 | #changelist .actions:last-child { 272 | border-bottom: none; 273 | } 274 | 275 | #changelist .actions select { 276 | border: 1px solid #aaa; 277 | margin-left: 0.5em; 278 | padding: 1px 2px; 279 | } 280 | 281 | #changelist .actions label { 282 | font-size: 11px; 283 | margin-left: 0.5em; 284 | } 285 | 286 | #changelist #action-toggle { 287 | display: none; 288 | } 289 | 290 | #changelist .actions .button { 291 | font-size: 11px; 292 | padding: 1px 2px; 293 | } 294 | -------------------------------------------------------------------------------- /Oliver/static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | } 25 | 26 | ul.actionlist li { 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | -o-text-overflow: ellipsis; 30 | } 31 | -------------------------------------------------------------------------------- /Oliver/static/admin/css/ie.css: -------------------------------------------------------------------------------- 1 | /* IE 6 & 7 */ 2 | 3 | /* Proper fixed width for dashboard in IE6 */ 4 | 5 | .dashboard #content { 6 | *width: 768px; 7 | } 8 | 9 | .dashboard #content-main { 10 | *width: 535px; 11 | } 12 | 13 | /* IE 6 ONLY */ 14 | 15 | /* Keep header from flowing off the page */ 16 | 17 | #container { 18 | _position: static; 19 | } 20 | 21 | /* Put the right sidebars back on the page */ 22 | 23 | .colMS #content-related { 24 | _margin-right: 0; 25 | _margin-left: 10px; 26 | _position: static; 27 | } 28 | 29 | /* Put the left sidebars back on the page */ 30 | 31 | .colSM #content-related { 32 | _margin-right: 10px; 33 | _margin-left: -115px; 34 | _position: static; 35 | } 36 | 37 | .form-row { 38 | _height: 1%; 39 | } 40 | 41 | /* Fix right margin for changelist filters in IE6 */ 42 | 43 | #changelist-filter ul { 44 | _margin-right: -10px; 45 | } 46 | 47 | /* IE ignores min-height, but treats height as if it were min-height */ 48 | 49 | .change-list .filtered { 50 | _height: 400px; 51 | } 52 | 53 | /* IE doesn't know alpha transparency in PNGs */ 54 | 55 | .inline-deletelink { 56 | background: transparent url(../img/inline-delete-8bit.png) no-repeat; 57 | } 58 | 59 | /* IE7 doesn't support inline-block */ 60 | .change-list ul.toplinks li { 61 | zoom: 1; 62 | *display: inline; 63 | } 64 | -------------------------------------------------------------------------------- /Oliver/static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #eee; 5 | } 6 | 7 | .login #container { 8 | background: white; 9 | border: 1px solid #ccc; 10 | width: 28em; 11 | min-width: 300px; 12 | margin-left: auto; 13 | margin-right: auto; 14 | margin-top: 100px; 15 | } 16 | 17 | .login #content-main { 18 | width: 100%; 19 | } 20 | 21 | .login form { 22 | margin-top: 1em; 23 | } 24 | 25 | .login .form-row { 26 | padding: 4px 0; 27 | float: left; 28 | width: 100%; 29 | } 30 | 31 | .login .form-row label { 32 | padding-right: 0.5em; 33 | line-height: 2em; 34 | font-size: 1em; 35 | clear: both; 36 | color: #333; 37 | } 38 | 39 | .login .form-row #id_username, .login .form-row #id_password { 40 | clear: both; 41 | padding: 6px; 42 | width: 100%; 43 | -webkit-box-sizing: border-box; 44 | -moz-box-sizing: border-box; 45 | box-sizing: border-box; 46 | } 47 | 48 | .login span.help { 49 | font-size: 10px; 50 | display: block; 51 | } 52 | 53 | .login .submit-row { 54 | clear: both; 55 | padding: 1em 0 0 9.4em; 56 | } 57 | 58 | .login .password-reset-link { 59 | text-align: center; 60 | } 61 | -------------------------------------------------------------------------------- /Oliver/static/admin/css/rtl.css: -------------------------------------------------------------------------------- 1 | body { 2 | direction: rtl; 3 | } 4 | 5 | /* LOGIN */ 6 | 7 | .login .form-row { 8 | float: right; 9 | } 10 | 11 | .login .form-row label { 12 | float: right; 13 | padding-left: 0.5em; 14 | padding-right: 0; 15 | text-align: left; 16 | } 17 | 18 | .login .submit-row { 19 | clear: both; 20 | padding: 1em 9.4em 0 0; 21 | } 22 | 23 | /* GLOBAL */ 24 | 25 | th { 26 | text-align: right; 27 | } 28 | 29 | .module h2, .module caption { 30 | text-align: right; 31 | } 32 | 33 | .addlink, .changelink { 34 | padding-left: 0px; 35 | padding-right: 12px; 36 | background-position: 100% 0.2em; 37 | } 38 | 39 | .deletelink { 40 | padding-left: 0px; 41 | padding-right: 12px; 42 | background-position: 100% 0.25em; 43 | } 44 | 45 | .object-tools { 46 | float: left; 47 | } 48 | 49 | thead th:first-child, 50 | tfoot td:first-child { 51 | border-left: 1px solid #ddd !important; 52 | } 53 | 54 | /* LAYOUT */ 55 | 56 | #user-tools { 57 | right: auto; 58 | left: 0; 59 | text-align: left; 60 | } 61 | 62 | div.breadcrumbs { 63 | text-align: right; 64 | } 65 | 66 | #content-main { 67 | float: right; 68 | } 69 | 70 | #content-related { 71 | float: left; 72 | margin-left: -19em; 73 | margin-right: auto; 74 | } 75 | 76 | .colMS { 77 | margin-left: 20em !important; 78 | margin-right: 10px !important; 79 | } 80 | 81 | /* SORTABLE TABLES */ 82 | 83 | table thead th.sorted .sortoptions { 84 | float: left; 85 | } 86 | 87 | thead th.sorted .text { 88 | padding-right: 0; 89 | padding-left: 42px; 90 | } 91 | 92 | /* dashboard styles */ 93 | 94 | .dashboard .module table td a { 95 | padding-left: .6em; 96 | padding-right: 12px; 97 | } 98 | 99 | /* changelists styles */ 100 | 101 | .change-list .filtered { 102 | background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important; 103 | } 104 | 105 | .change-list .filtered table { 106 | border-left: 1px solid #ddd; 107 | border-right: 0px none; 108 | } 109 | 110 | #changelist-filter { 111 | right: auto; 112 | left: 0; 113 | border-left: 0px none; 114 | border-right: 1px solid #ddd; 115 | } 116 | 117 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 118 | margin-right: 0px !important; 119 | margin-left: 160px !important; 120 | } 121 | 122 | #changelist-filter li.selected { 123 | border-left: 0px none; 124 | padding-left: 0px; 125 | margin-left: 0; 126 | border-right: 5px solid #ccc; 127 | padding-right: 5px; 128 | margin-right: -10px; 129 | } 130 | 131 | .filtered .actions { 132 | border-left:1px solid #DDDDDD; 133 | margin-left:160px !important; 134 | border-right: 0 none; 135 | margin-right:0 !important; 136 | } 137 | 138 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 139 | border-right: 0; 140 | border-left: 1px solid #ddd; 141 | } 142 | 143 | /* FORMS */ 144 | 145 | .aligned label { 146 | padding: 0 0 3px 1em; 147 | float: right; 148 | } 149 | 150 | .submit-row { 151 | text-align: left 152 | } 153 | 154 | .submit-row p.deletelink-box { 155 | float: right; 156 | } 157 | 158 | .submit-row .deletelink { 159 | background: url(../img/icon_deletelink.gif) 0 50% no-repeat; 160 | padding-right: 14px; 161 | } 162 | 163 | .vDateField, .vTimeField { 164 | margin-left: 2px; 165 | } 166 | 167 | form ul.inline li { 168 | float: right; 169 | padding-right: 0; 170 | padding-left: 7px; 171 | } 172 | 173 | input[type=submit].default, .submit-row input.default { 174 | float: left; 175 | } 176 | 177 | fieldset .field-box { 178 | float: right; 179 | margin-left: 20px; 180 | margin-right: 0; 181 | } 182 | 183 | .errorlist li { 184 | background-position: 100% .3em; 185 | padding: 4px 25px 4px 5px; 186 | } 187 | 188 | .errornote { 189 | background-position: 100% .3em; 190 | padding: 4px 25px 4px 5px; 191 | } 192 | 193 | /* WIDGETS */ 194 | 195 | .calendarnav-previous { 196 | top: 0; 197 | left: auto; 198 | right: 0; 199 | } 200 | 201 | .calendarnav-next { 202 | top: 0; 203 | right: auto; 204 | left: 0; 205 | } 206 | 207 | .calendar caption, .calendarbox h2 { 208 | text-align: center; 209 | } 210 | 211 | .selector { 212 | float: right; 213 | } 214 | 215 | .selector .selector-filter { 216 | text-align: right; 217 | } 218 | 219 | .inline-deletelink { 220 | float: left; 221 | } 222 | 223 | /* MISC */ 224 | 225 | .inline-related h2, .inline-group h2 { 226 | text-align: right 227 | } 228 | 229 | .inline-related h3 span.delete { 230 | padding-right: 20px; 231 | padding-left: inherit; 232 | left: 10px; 233 | right: inherit; 234 | float:left; 235 | } 236 | 237 | .inline-related h3 span.delete label { 238 | margin-left: inherit; 239 | margin-right: 2px; 240 | } 241 | 242 | /* IE7 specific bug fixes */ 243 | 244 | div.colM { 245 | position: relative; 246 | } 247 | 248 | .submit-row input { 249 | float: left; 250 | } 251 | -------------------------------------------------------------------------------- /Oliver/static/admin/img/changelist-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/changelist-bg.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/changelist-bg_rtl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/changelist-bg_rtl.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/default-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/default-bg-reverse.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/default-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/default-bg.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/deleted-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/deleted-overlay.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/gis/move_vertex_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/gis/move_vertex_off.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/gis/move_vertex_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/gis/move_vertex_on.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon-no.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon-no.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon-unknown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon-unknown.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon-yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon-yes.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_addlink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_addlink.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_alert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_alert.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_calendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_calendar.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_changelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_changelink.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_clock.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_deletelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_deletelink.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_error.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_searchbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_searchbox.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/icon_success.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/icon_success.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/inline-delete-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/inline-delete-8bit.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/inline-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/inline-delete.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/inline-restore-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/inline-restore-8bit.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/inline-restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/inline-restore.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/inline-splitter-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/inline-splitter-bg.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/nav-bg-grabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/nav-bg-grabber.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/nav-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/nav-bg-reverse.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/nav-bg-selected.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/nav-bg-selected.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/nav-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/nav-bg.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/selector-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/selector-icons.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/selector-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/selector-search.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/sorting-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/sorting-icons.gif -------------------------------------------------------------------------------- /Oliver/static/admin/img/tooltag-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/tooltag-add.png -------------------------------------------------------------------------------- /Oliver/static/admin/img/tooltag-arrowright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldtian/Oliver/8697c804c99e77d2025487036c7c0d3ac25549cd/Oliver/static/admin/img/tooltag-arrowright.png -------------------------------------------------------------------------------- /Oliver/static/admin/js/LICENSE-JQUERY.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Oliver/static/admin/js/SelectBox.js: -------------------------------------------------------------------------------- 1 | var SelectBox = { 2 | cache: new Object(), 3 | init: function(id) { 4 | var box = document.getElementById(id); 5 | var node; 6 | SelectBox.cache[id] = new Array(); 7 | var cache = SelectBox.cache[id]; 8 | for (var i = 0; (node = box.options[i]); i++) { 9 | cache.push({value: node.value, text: node.text, displayed: 1}); 10 | } 11 | }, 12 | redisplay: function(id) { 13 | // Repopulate HTML select box from cache 14 | var box = document.getElementById(id); 15 | box.options.length = 0; // clear all options 16 | for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { 17 | var node = SelectBox.cache[id][i]; 18 | if (node.displayed) { 19 | var new_option = new Option(node.text, node.value, false, false); 20 | // Shows a tooltip when hovering over the option 21 | new_option.setAttribute("title", node.text); 22 | box.options[box.options.length] = new_option; 23 | } 24 | } 25 | }, 26 | filter: function(id, text) { 27 | // Redisplay the HTML select box, displaying only the choices containing ALL 28 | // the words in text. (It's an AND search.) 29 | var tokens = text.toLowerCase().split(/\s+/); 30 | var node, token; 31 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 32 | node.displayed = 1; 33 | for (var j = 0; (token = tokens[j]); j++) { 34 | if (node.text.toLowerCase().indexOf(token) == -1) { 35 | node.displayed = 0; 36 | } 37 | } 38 | } 39 | SelectBox.redisplay(id); 40 | }, 41 | delete_from_cache: function(id, value) { 42 | var node, delete_index = null; 43 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 44 | if (node.value == value) { 45 | delete_index = i; 46 | break; 47 | } 48 | } 49 | var j = SelectBox.cache[id].length - 1; 50 | for (var i = delete_index; i < j; i++) { 51 | SelectBox.cache[id][i] = SelectBox.cache[id][i+1]; 52 | } 53 | SelectBox.cache[id].length--; 54 | }, 55 | add_to_cache: function(id, option) { 56 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); 57 | }, 58 | cache_contains: function(id, value) { 59 | // Check if an item is contained in the cache 60 | var node; 61 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 62 | if (node.value == value) { 63 | return true; 64 | } 65 | } 66 | return false; 67 | }, 68 | move: function(from, to) { 69 | var from_box = document.getElementById(from); 70 | var to_box = document.getElementById(to); 71 | var option; 72 | for (var i = 0; (option = from_box.options[i]); i++) { 73 | if (option.selected && SelectBox.cache_contains(from, option.value)) { 74 | SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); 75 | SelectBox.delete_from_cache(from, option.value); 76 | } 77 | } 78 | SelectBox.redisplay(from); 79 | SelectBox.redisplay(to); 80 | }, 81 | move_all: function(from, to) { 82 | var from_box = document.getElementById(from); 83 | var to_box = document.getElementById(to); 84 | var option; 85 | for (var i = 0; (option = from_box.options[i]); i++) { 86 | if (SelectBox.cache_contains(from, option.value)) { 87 | SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); 88 | SelectBox.delete_from_cache(from, option.value); 89 | } 90 | } 91 | SelectBox.redisplay(from); 92 | SelectBox.redisplay(to); 93 | }, 94 | sort: function(id) { 95 | SelectBox.cache[id].sort( function(a, b) { 96 | a = a.text.toLowerCase(); 97 | b = b.text.toLowerCase(); 98 | try { 99 | if (a > b) return 1; 100 | if (a < b) return -1; 101 | } 102 | catch (e) { 103 | // silently fail on IE 'unknown' exception 104 | } 105 | return 0; 106 | } ); 107 | }, 108 | select_all: function(id) { 109 | var box = document.getElementById(id); 110 | for (var i = 0; i < box.options.length; i++) { 111 | box.options[i].selected = 'selected'; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/actions.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | var lastChecked; 3 | 4 | $.fn.actions = function(opts) { 5 | var options = $.extend({}, $.fn.actions.defaults, opts); 6 | var actionCheckboxes = $(this); 7 | var list_editable_changed = false; 8 | var checker = function(checked) { 9 | if (checked) { 10 | showQuestion(); 11 | } else { 12 | reset(); 13 | } 14 | $(actionCheckboxes).prop("checked", checked) 15 | .parent().parent().toggleClass(options.selectedClass, checked); 16 | }, 17 | updateCounter = function() { 18 | var sel = $(actionCheckboxes).filter(":checked").length; 19 | // _actions_icnt is defined in the generated HTML 20 | // and contains the total amount of objects in the queryset 21 | $(options.counterContainer).html(interpolate( 22 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { 23 | sel: sel, 24 | cnt: _actions_icnt 25 | }, true)); 26 | $(options.allToggle).prop("checked", function() { 27 | var value; 28 | if (sel == actionCheckboxes.length) { 29 | value = true; 30 | showQuestion(); 31 | } else { 32 | value = false; 33 | clearAcross(); 34 | } 35 | return value; 36 | }); 37 | }, 38 | showQuestion = function() { 39 | $(options.acrossClears).hide(); 40 | $(options.acrossQuestions).show(); 41 | $(options.allContainer).hide(); 42 | }, 43 | showClear = function() { 44 | $(options.acrossClears).show(); 45 | $(options.acrossQuestions).hide(); 46 | $(options.actionContainer).toggleClass(options.selectedClass); 47 | $(options.allContainer).show(); 48 | $(options.counterContainer).hide(); 49 | }, 50 | reset = function() { 51 | $(options.acrossClears).hide(); 52 | $(options.acrossQuestions).hide(); 53 | $(options.allContainer).hide(); 54 | $(options.counterContainer).show(); 55 | }, 56 | clearAcross = function() { 57 | reset(); 58 | $(options.acrossInput).val(0); 59 | $(options.actionContainer).removeClass(options.selectedClass); 60 | }; 61 | // Show counter by default 62 | $(options.counterContainer).show(); 63 | // Check state of checkboxes and reinit state if needed 64 | $(this).filter(":checked").each(function(i) { 65 | $(this).parent().parent().toggleClass(options.selectedClass); 66 | updateCounter(); 67 | if ($(options.acrossInput).val() == 1) { 68 | showClear(); 69 | } 70 | }); 71 | $(options.allToggle).show().click(function() { 72 | checker($(this).prop("checked")); 73 | updateCounter(); 74 | }); 75 | $("a", options.acrossQuestions).click(function(event) { 76 | event.preventDefault(); 77 | $(options.acrossInput).val(1); 78 | showClear(); 79 | }); 80 | $("a", options.acrossClears).click(function(event) { 81 | event.preventDefault(); 82 | $(options.allToggle).prop("checked", false); 83 | clearAcross(); 84 | checker(0); 85 | updateCounter(); 86 | }); 87 | lastChecked = null; 88 | $(actionCheckboxes).click(function(event) { 89 | if (!event) { event = window.event; } 90 | var target = event.target ? event.target : event.srcElement; 91 | if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) { 92 | var inrange = false; 93 | $(lastChecked).prop("checked", target.checked) 94 | .parent().parent().toggleClass(options.selectedClass, target.checked); 95 | $(actionCheckboxes).each(function() { 96 | if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { 97 | inrange = (inrange) ? false : true; 98 | } 99 | if (inrange) { 100 | $(this).prop("checked", target.checked) 101 | .parent().parent().toggleClass(options.selectedClass, target.checked); 102 | } 103 | }); 104 | } 105 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked); 106 | lastChecked = target; 107 | updateCounter(); 108 | }); 109 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { 110 | list_editable_changed = true; 111 | }); 112 | $('form#changelist-form button[name="index"]').click(function(event) { 113 | if (list_editable_changed) { 114 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); 115 | } 116 | }); 117 | $('form#changelist-form input[name="_save"]').click(function(event) { 118 | var action_changed = false; 119 | $('select option:selected', options.actionContainer).each(function() { 120 | if ($(this).val()) { 121 | action_changed = true; 122 | } 123 | }); 124 | if (action_changed) { 125 | if (list_editable_changed) { 126 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); 127 | } else { 128 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); 129 | } 130 | } 131 | }); 132 | }; 133 | /* Setup plugin defaults */ 134 | $.fn.actions.defaults = { 135 | actionContainer: "div.actions", 136 | counterContainer: "span.action-counter", 137 | allContainer: "div.actions span.all", 138 | acrossInput: "div.actions input.select-across", 139 | acrossQuestions: "div.actions span.question", 140 | acrossClears: "div.actions span.clear", 141 | allToggle: "#action-toggle", 142 | selectedClass: "selected" 143 | }; 144 | })(django.jQuery); 145 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide(); 2 | a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass); 3 | h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass, 4 | d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))}); 5 | a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})}; 6 | a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery); 7 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/admin/RelatedObjectLookups.js: -------------------------------------------------------------------------------- 1 | // Handles related-objects functionality: lookup link for raw_id_fields 2 | // and Add Another links. 3 | 4 | function html_unescape(text) { 5 | // Unescape a string that was escaped using django.utils.html.escape. 6 | text = text.replace(/</g, '<'); 7 | text = text.replace(/>/g, '>'); 8 | text = text.replace(/"/g, '"'); 9 | text = text.replace(/'/g, "'"); 10 | text = text.replace(/&/g, '&'); 11 | return text; 12 | } 13 | 14 | // IE doesn't accept periods or dashes in the window name, but the element IDs 15 | // we use to generate popup window names may contain them, therefore we map them 16 | // to allowed characters in a reversible way so that we can locate the correct 17 | // element when the popup window is dismissed. 18 | function id_to_windowname(text) { 19 | text = text.replace(/\./g, '__dot__'); 20 | text = text.replace(/\-/g, '__dash__'); 21 | return text; 22 | } 23 | 24 | function windowname_to_id(text) { 25 | text = text.replace(/__dot__/g, '.'); 26 | text = text.replace(/__dash__/g, '-'); 27 | return text; 28 | } 29 | 30 | function showAdminPopup(triggeringLink, name_regexp) { 31 | var name = triggeringLink.id.replace(name_regexp, ''); 32 | name = id_to_windowname(name); 33 | var href = triggeringLink.href; 34 | if (href.indexOf('?') == -1) { 35 | href += '?_popup=1'; 36 | } else { 37 | href += '&_popup=1'; 38 | } 39 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 40 | win.focus(); 41 | return false; 42 | } 43 | 44 | function showRelatedObjectLookupPopup(triggeringLink) { 45 | return showAdminPopup(triggeringLink, /^lookup_/); 46 | } 47 | 48 | function dismissRelatedLookupPopup(win, chosenId) { 49 | var name = windowname_to_id(win.name); 50 | var elem = document.getElementById(name); 51 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 52 | elem.value += ',' + chosenId; 53 | } else { 54 | document.getElementById(name).value = chosenId; 55 | } 56 | win.close(); 57 | } 58 | 59 | function showRelatedObjectPopup(triggeringLink) { 60 | var name = triggeringLink.id.replace(/^(change|add|delete)_/, ''); 61 | name = id_to_windowname(name); 62 | var href = triggeringLink.href; 63 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 64 | win.focus(); 65 | return false; 66 | } 67 | 68 | function dismissAddRelatedObjectPopup(win, newId, newRepr) { 69 | // newId and newRepr are expected to have previously been escaped by 70 | // django.utils.html.escape. 71 | newId = html_unescape(newId); 72 | newRepr = html_unescape(newRepr); 73 | var name = windowname_to_id(win.name); 74 | var elem = document.getElementById(name); 75 | var o; 76 | if (elem) { 77 | var elemName = elem.nodeName.toUpperCase(); 78 | if (elemName == 'SELECT') { 79 | o = new Option(newRepr, newId); 80 | elem.options[elem.options.length] = o; 81 | o.selected = true; 82 | } else if (elemName == 'INPUT') { 83 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 84 | elem.value += ',' + newId; 85 | } else { 86 | elem.value = newId; 87 | } 88 | } 89 | // Trigger a change event to update related links if required. 90 | django.jQuery(elem).trigger('change'); 91 | } else { 92 | var toId = name + "_to"; 93 | o = new Option(newRepr, newId); 94 | SelectBox.add_to_cache(toId, o); 95 | SelectBox.redisplay(toId); 96 | } 97 | win.close(); 98 | } 99 | 100 | function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { 101 | objId = html_unescape(objId); 102 | newRepr = html_unescape(newRepr); 103 | var id = windowname_to_id(win.name).replace(/^edit_/, ''); 104 | var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); 105 | var selects = django.jQuery(selectsSelector); 106 | selects.find('option').each(function() { 107 | if (this.value == objId) { 108 | this.innerHTML = newRepr; 109 | this.value = newId; 110 | } 111 | }); 112 | win.close(); 113 | }; 114 | 115 | function dismissDeleteRelatedObjectPopup(win, objId) { 116 | objId = html_unescape(objId); 117 | var id = windowname_to_id(win.name).replace(/^delete_/, ''); 118 | var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); 119 | var selects = django.jQuery(selectsSelector); 120 | selects.find('option').each(function() { 121 | if (this.value == objId) { 122 | django.jQuery(this).remove(); 123 | } 124 | }).trigger('change'); 125 | win.close(); 126 | }; 127 | 128 | // Kept for backward compatibility 129 | showAddAnotherPopup = showRelatedObjectPopup; 130 | dismissAddAnotherPopup = dismissAddRelatedObjectPopup; 131 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/calendar.js: -------------------------------------------------------------------------------- 1 | /* 2 | calendar.js - Calendar functions by Adrian Holovaty 3 | depends on core.js for utility functions like removeChildren or quickElement 4 | */ 5 | 6 | // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions 7 | var CalendarNamespace = { 8 | monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), 9 | daysOfWeek: gettext('S M T W T F S').split(' '), 10 | firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), 11 | isLeapYear: function(year) { 12 | return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)); 13 | }, 14 | getDaysInMonth: function(month,year) { 15 | var days; 16 | if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) { 17 | days = 31; 18 | } 19 | else if (month==4 || month==6 || month==9 || month==11) { 20 | days = 30; 21 | } 22 | else if (month==2 && CalendarNamespace.isLeapYear(year)) { 23 | days = 29; 24 | } 25 | else { 26 | days = 28; 27 | } 28 | return days; 29 | }, 30 | draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 31 | var today = new Date(); 32 | var todayDay = today.getDate(); 33 | var todayMonth = today.getMonth()+1; 34 | var todayYear = today.getFullYear(); 35 | var todayClass = ''; 36 | 37 | // Use UTC functions here because the date field does not contain time 38 | // and using the UTC function variants prevent the local time offset 39 | // from altering the date, specifically the day field. For example: 40 | // 41 | // ``` 42 | // var x = new Date('2013-10-02'); 43 | // var day = x.getDate(); 44 | // ``` 45 | // 46 | // The day variable above will be 1 instead of 2 in, say, US Pacific time 47 | // zone. 48 | var isSelectedMonth = false; 49 | if (typeof selected != 'undefined') { 50 | isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month); 51 | } 52 | 53 | month = parseInt(month); 54 | year = parseInt(year); 55 | var calDiv = document.getElementById(div_id); 56 | removeChildren(calDiv); 57 | var calTable = document.createElement('table'); 58 | quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year); 59 | var tableBody = quickElement('tbody', calTable); 60 | 61 | // Draw days-of-week header 62 | var tableRow = quickElement('tr', tableBody); 63 | for (var i = 0; i < 7; i++) { 64 | quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); 65 | } 66 | 67 | var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); 68 | var days = CalendarNamespace.getDaysInMonth(month, year); 69 | 70 | // Draw blanks before first of month 71 | tableRow = quickElement('tr', tableBody); 72 | for (var i = 0; i < startingPos; i++) { 73 | var _cell = quickElement('td', tableRow, ' '); 74 | _cell.className = "nonday"; 75 | } 76 | 77 | // Draw days of month 78 | var currentDay = 1; 79 | for (var i = startingPos; currentDay <= days; i++) { 80 | if (i%7 == 0 && currentDay != 1) { 81 | tableRow = quickElement('tr', tableBody); 82 | } 83 | if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) { 84 | todayClass='today'; 85 | } else { 86 | todayClass=''; 87 | } 88 | 89 | // use UTC function; see above for explanation. 90 | if (isSelectedMonth && currentDay == selected.getUTCDate()) { 91 | if (todayClass != '') todayClass += " "; 92 | todayClass += "selected"; 93 | } 94 | 95 | var cell = quickElement('td', tableRow, '', 'class', todayClass); 96 | 97 | quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));'); 98 | currentDay++; 99 | } 100 | 101 | // Draw blanks after end of month (optional, but makes for valid code) 102 | while (tableRow.childNodes.length < 7) { 103 | var _cell = quickElement('td', tableRow, ' '); 104 | _cell.className = "nonday"; 105 | } 106 | 107 | calDiv.appendChild(calTable); 108 | } 109 | } 110 | 111 | // Calendar -- A calendar instance 112 | function Calendar(div_id, callback, selected) { 113 | // div_id (string) is the ID of the element in which the calendar will 114 | // be displayed 115 | // callback (string) is the name of a JavaScript function that will be 116 | // called with the parameters (year, month, day) when a day in the 117 | // calendar is clicked 118 | this.div_id = div_id; 119 | this.callback = callback; 120 | this.today = new Date(); 121 | this.currentMonth = this.today.getMonth() + 1; 122 | this.currentYear = this.today.getFullYear(); 123 | if (typeof selected != 'undefined') { 124 | this.selected = selected; 125 | } 126 | } 127 | Calendar.prototype = { 128 | drawCurrent: function() { 129 | CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); 130 | }, 131 | drawDate: function(month, year, selected) { 132 | this.currentMonth = month; 133 | this.currentYear = year; 134 | 135 | if(selected) { 136 | this.selected = selected; 137 | } 138 | 139 | this.drawCurrent(); 140 | }, 141 | drawPreviousMonth: function() { 142 | if (this.currentMonth == 1) { 143 | this.currentMonth = 12; 144 | this.currentYear--; 145 | } 146 | else { 147 | this.currentMonth--; 148 | } 149 | this.drawCurrent(); 150 | }, 151 | drawNextMonth: function() { 152 | if (this.currentMonth == 12) { 153 | this.currentMonth = 1; 154 | this.currentYear++; 155 | } 156 | else { 157 | this.currentMonth++; 158 | } 159 | this.drawCurrent(); 160 | }, 161 | drawPreviousYear: function() { 162 | this.currentYear--; 163 | this.drawCurrent(); 164 | }, 165 | drawNextYear: function() { 166 | this.currentYear++; 167 | this.drawCurrent(); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/collapse.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(document).ready(function() { 3 | // Add anchor tag for Show/Hide link 4 | $("fieldset.collapse").each(function(i, elem) { 5 | // Don't hide if fields in this fieldset have errors 6 | if ($(elem).find("div.errors").length == 0) { 7 | $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + 9 | ')'); 10 | } 11 | }); 12 | // Add toggle to anchor tag 13 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 14 | if ($(this).closest("fieldset").hasClass("collapsed")) { 15 | // Show 16 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 17 | } else { 18 | // Hide 19 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 20 | } 21 | return false; 22 | }); 23 | }); 24 | })(django.jQuery); 25 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return false})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/inlines.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a.fn.formset=function(g){var b=a.extend({},a.fn.formset.defaults,g),i=a(this);g=i.parent();var m=function(e,k,h){var j=RegExp("("+k+"-(\\d+|__prefix__))");k=k+"-"+h;a(e).prop("for")&&a(e).prop("for",a(e).prop("for").replace(j,k));if(e.id)e.id=e.id.replace(j,k);if(e.name)e.name=e.name.replace(j,k)},l=a("#id_"+b.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),d=parseInt(l.val(),10),c=a("#id_"+b.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off");l=c.val()===""||c.val()-l.val()>0;i.each(function(){a(this).not("."+ 2 | b.emptyCssClass).addClass(b.formCssClass)});if(i.length&&l){var f;if(i.prop("tagName")=="TR"){i=this.eq(-1).children().length;g.append(''+b.addText+"");f=g.find("tr:last a")}else{i.filter(":last").after('");f=i.filter(":last").next().find("a")}f.click(function(e){e.preventDefault();var k=a("#id_"+b.prefix+"-TOTAL_FORMS");e=a("#"+ 3 | b.prefix+"-empty");var h=e.clone(true);h.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+"-"+d);if(h.is("tr"))h.children(":last").append('");else h.is("ul")||h.is("ol")?h.append('
  • '+b.deleteText+"
  • "):h.children(":first").append(''+b.deleteText+""); 4 | h.find("*").each(function(){m(this,b.prefix,k.val())});h.insertBefore(a(e));a(k).val(parseInt(k.val(),10)+1);d+=1;c.val()!==""&&c.val()-k.val()<=0&&f.parent().hide();h.find("a."+b.deleteCssClass).click(function(j){j.preventDefault();j=a(this).parents("."+b.formCssClass);j.remove();d-=1;b.removed&&b.removed(j);j=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(j.length);if(c.val()===""||c.val()-j.length>0)f.parent().show();for(var n=0,o=j.length;n 0) { 23 | values.push(field.val()); 24 | } 25 | }); 26 | prepopulatedField.val(URLify(values.join(' '), maxLength)); 27 | }; 28 | 29 | prepopulatedField.data('_changed', false); 30 | prepopulatedField.change(function() { 31 | prepopulatedField.data('_changed', true); 32 | }); 33 | 34 | if (!prepopulatedField.val()) { 35 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); 36 | } 37 | }); 38 | }; 39 | })(django.jQuery); 40 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery); 2 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/related-widget-wrapper.js: -------------------------------------------------------------------------------- 1 | django.jQuery(function($){ 2 | function updateLinks() { 3 | var $this = $(this); 4 | var siblings = $this.nextAll('.change-related, .delete-related'); 5 | if (!siblings.length) return; 6 | var value = $this.val(); 7 | if (value) { 8 | siblings.each(function(){ 9 | var elm = $(this); 10 | elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); 11 | }); 12 | } else siblings.removeAttr('href'); 13 | } 14 | var container = $(document); 15 | container.on('change', '.related-widget-wrapper select', updateLinks); 16 | container.find('.related-widget-wrapper select').each(updateLinks); 17 | container.on('click', '.related-widget-wrapper-link', function(event){ 18 | if (this.href) { 19 | showRelatedObjectPopup(this); 20 | } 21 | event.preventDefault(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/timeparse.js: -------------------------------------------------------------------------------- 1 | var timeParsePatterns = [ 2 | // 9 3 | { re: /^\d{1,2}$/i, 4 | handler: function(bits) { 5 | if (bits[0].length == 1) { 6 | return '0' + bits[0] + ':00'; 7 | } else { 8 | return bits[0] + ':00'; 9 | } 10 | } 11 | }, 12 | // 13:00 13 | { re: /^\d{2}[:.]\d{2}$/i, 14 | handler: function(bits) { 15 | return bits[0].replace('.', ':'); 16 | } 17 | }, 18 | // 9:00 19 | { re: /^\d[:.]\d{2}$/i, 20 | handler: function(bits) { 21 | return '0' + bits[0].replace('.', ':'); 22 | } 23 | }, 24 | // 3 am / 3 a.m. / 3am 25 | { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, 26 | handler: function(bits) { 27 | var hour = parseInt(bits[1]); 28 | if (hour == 12) { 29 | hour = 0; 30 | } 31 | if (bits[2].toLowerCase() == 'p') { 32 | if (hour == 12) { 33 | hour = 0; 34 | } 35 | return (hour + 12) + ':00'; 36 | } else { 37 | if (hour < 10) { 38 | return '0' + hour + ':00'; 39 | } else { 40 | return hour + ':00'; 41 | } 42 | } 43 | } 44 | }, 45 | // 3.30 am / 3:15 a.m. / 3.00am 46 | { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, 47 | handler: function(bits) { 48 | var hour = parseInt(bits[1]); 49 | var mins = parseInt(bits[2]); 50 | if (mins < 10) { 51 | mins = '0' + mins; 52 | } 53 | if (hour == 12) { 54 | hour = 0; 55 | } 56 | if (bits[3].toLowerCase() == 'p') { 57 | if (hour == 12) { 58 | hour = 0; 59 | } 60 | return (hour + 12) + ':' + mins; 61 | } else { 62 | if (hour < 10) { 63 | return '0' + hour + ':' + mins; 64 | } else { 65 | return hour + ':' + mins; 66 | } 67 | } 68 | } 69 | }, 70 | // noon 71 | { re: /^no/i, 72 | handler: function(bits) { 73 | return '12:00'; 74 | } 75 | }, 76 | // midnight 77 | { re: /^mid/i, 78 | handler: function(bits) { 79 | return '00:00'; 80 | } 81 | } 82 | ]; 83 | 84 | function parseTimeString(s) { 85 | for (var i = 0; i < timeParsePatterns.length; i++) { 86 | var re = timeParsePatterns[i].re; 87 | var handler = timeParsePatterns[i].handler; 88 | var bits = re.exec(s); 89 | if (bits) { 90 | return handler(bits); 91 | } 92 | } 93 | return s; 94 | } 95 | -------------------------------------------------------------------------------- /Oliver/static/admin/js/urlify.js: -------------------------------------------------------------------------------- 1 | var LATIN_MAP = { 2 | 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 3 | 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 4 | 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 5 | 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', 6 | 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 7 | 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 8 | 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 9 | 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 10 | 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' 11 | }; 12 | var LATIN_SYMBOLS_MAP = { 13 | '©':'(c)' 14 | }; 15 | var GREEK_MAP = { 16 | 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8', 17 | 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p', 18 | 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', 19 | 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', 20 | 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', 21 | 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', 22 | 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', 23 | 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W', 24 | 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', 25 | 'Ϋ':'Y' 26 | }; 27 | var TURKISH_MAP = { 28 | 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U', 29 | 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G' 30 | }; 31 | var RUSSIAN_MAP = { 32 | 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh', 33 | 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', 34 | 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', 35 | 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', 36 | 'я':'ya', 37 | 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh', 38 | 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O', 39 | 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C', 40 | 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', 41 | 'Я':'Ya' 42 | }; 43 | var UKRAINIAN_MAP = { 44 | 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g' 45 | }; 46 | var CZECH_MAP = { 47 | 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', 48 | 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T', 49 | 'Ů':'U', 'Ž':'Z' 50 | }; 51 | var POLISH_MAP = { 52 | 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z', 53 | 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S', 54 | 'Ź':'Z', 'Ż':'Z' 55 | }; 56 | var LATVIAN_MAP = { 57 | 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n', 58 | 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I', 59 | 'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z' 60 | }; 61 | var ARABIC_MAP = { 62 | 'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d', 63 | 'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t', 64 | 'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', 65 | 'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' 66 | }; 67 | var LITHUANIAN_MAP = { 68 | 'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', 69 | 'ž':'z', 70 | 'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U', 71 | 'Ž':'Z' 72 | }; 73 | var SERBIAN_MAP = { 74 | 'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj', 75 | 'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj' 76 | }; 77 | var AZERBAIJANI_MAP = { 78 | 'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u', 79 | 'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U' 80 | }; 81 | 82 | var ALL_DOWNCODE_MAPS = [ 83 | LATIN_MAP, 84 | LATIN_SYMBOLS_MAP, 85 | GREEK_MAP, 86 | TURKISH_MAP, 87 | RUSSIAN_MAP, 88 | UKRAINIAN_MAP, 89 | CZECH_MAP, 90 | POLISH_MAP, 91 | LATVIAN_MAP, 92 | ARABIC_MAP, 93 | LITHUANIAN_MAP, 94 | SERBIAN_MAP, 95 | AZERBAIJANI_MAP 96 | ]; 97 | 98 | var Downcoder = { 99 | 'Initialize': function() { 100 | if (Downcoder.map) { // already made 101 | return; 102 | } 103 | Downcoder.map = {}; 104 | Downcoder.chars = []; 105 | for (var i=0; i 2 | 3 | 4 | 5 | 6 | 7 | {% block title %}欢迎使用{% endblock %} - 运维管理系统 8 | 9 | 30 | 31 | 32 | {% include "nav.html" %} 33 |
    34 |
    35 |
    36 |
    37 |
    38 |

    39 |

    40 |
    41 |
    42 | {% include "left-menu.html" %} 43 |
    44 |
    45 |
    46 |
    47 |
    48 |
    49 | {% include "top-icon.html" %} 50 |
    51 |
    52 |
    53 |
    54 |

    55 | {% block panel-title %} 56 | Oliver运维管理系统 57 | {% endblock %} 58 |

    59 |
    60 |
    61 | {% block content %} 62 | 63 | {% endblock %} 64 |
    65 |
    66 | 67 |
    68 |
    69 |
    70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Oliver/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | {% block title %} 3 | 首页 4 | {% endblock %} 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |
    11 |
    12 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/left-menu.20160415.html: -------------------------------------------------------------------------------- 1 | 首页 2 | 主机管理 3 | 主机组管理 4 | 网站监控 5 | 运维管理 6 | 安全审计 7 | 查询统计 -------------------------------------------------------------------------------- /Oliver/templates/left-menu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |   首  页 4 | 5 | 6 | 7 | 8 |   主机管理 9 | 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 | -------------------------------------------------------------------------------- /Oliver/templates/nav.20160415.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Oliver/templates/nav.html: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /Oliver/templates/test.html: -------------------------------------------------------------------------------- 1 |
    2 | Name: 3 | 4 |
    -------------------------------------------------------------------------------- /Oliver/templates/top-icon.html: -------------------------------------------------------------------------------- 1 | 6 | 11 | 16 | 21 | 26 | 31 | 36 | -------------------------------------------------------------------------------- /Oliver/templates/ywweb/addhostgroup.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %}添加主机组{% endblock %} 4 | 5 | {% block panel-title %} 6 | 添加主机组 7 | {% endblock %} 8 | 9 | 10 | {% block content %} 11 |
    12 | {% csrf_token %} 13 |
    14 | 15 |
    16 | 18 |
    19 |
    20 |
    21 | 22 |
    23 | 32 |
    33 |
    34 | 35 |

    36 | 37 |
    38 |
    39 | 41 |
    42 |
    43 | 44 |
    45 |
    46 | 47 | 48 |
    49 |
    50 |
    51 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/ywweb/addmodule.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %}添加模块{% endblock %} 4 | 5 | {% block panel-title %}添加模块{% endblock %} 6 | 7 | {% block content %} 8 |
    9 | {% csrf_token %} 10 |
    11 | 12 |
    13 | 15 |
    16 |
    17 |
    18 | 19 |
    20 | 22 |
    23 |
    24 |
    25 | 26 |
    27 | 28 |
    29 |
    30 |

    * 系统支持表单扩展参数, ID命名约定为"sys_param_1"

    31 |
    32 |
    33 | 34 | 35 |
    36 |
    37 |
    38 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/ywweb/addweb.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %} 4 | 添加站点 5 | {% endblock %} 6 | 7 | {% block panel-title %} 8 | 添加新站点 9 | {% endblock %} 10 | 11 | {% block content %} 12 |
    13 | {% csrf_token %} 14 |
    15 | 16 |
    17 | 19 |
    20 |
    21 |
    22 | 23 |
    24 | 26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 | 33 |
    34 |
    35 |
    36 | {% endblock %} 37 | 38 | -------------------------------------------------------------------------------- /Oliver/templates/ywweb/audit.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %}安全审计{% endblock %} 4 | 5 | {% block panel-title %}安全审计{% endblock %} 6 | 7 | {% block content %} 8 |
    9 | 14 |
    15 |
    16 | 19 |
    20 |
    21 | 28 |
    29 |
    30 |
    31 |
    32 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/ywweb/edithostgroup.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %}编辑主机组{% endblock %} 4 | 5 | {% block panel-title %} 6 | 编辑主机组"{{hostgroup.name}}" 7 | {% endblock %} 8 | 9 | 10 | {% block content %} 11 |
    12 | {% csrf_token %} 13 |
    14 | 15 |
    16 | 18 |
    19 |
    20 |
    21 | 22 |
    23 | 32 |
    33 |
    34 | 35 |

    36 | 37 |
    38 |
    39 | 48 |
    49 |
    50 | 51 |
    52 |
    53 | 54 | 55 |
    56 |
    57 |
    58 | 59 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/ywweb/editweb.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %} 4 | 编辑站点 5 | {% endblock %} 6 | 7 | {% block panel-title %} 8 | 编辑站点"{{site.name}}" 9 | {% endblock %} 10 | 11 | {% block content %} 12 |
    13 | {% csrf_token %} 14 |
    15 | 16 |
    17 | 19 |
    20 |
    21 |
    22 | 23 |
    24 | 26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 | 33 |
    34 |
    35 |
    36 | {% endblock %} 37 | 38 | -------------------------------------------------------------------------------- /Oliver/templates/ywweb/hostgroup.html: -------------------------------------------------------------------------------- 1 | {% extends "bstrap.html" %} 2 | 3 | {% block title %}主机组管理{% endblock %} 4 | 5 | {% block panel-title %} 6 | 主机组管理 7 | {% endblock %} 8 | 9 | {% block content %} 10 | 11 |
    12 | 17 |
    18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% for group in hostgroup %} 28 | 29 | 30 | 31 | 32 | {% endfor %} 33 | 34 |
    组名成员
    {{group.name}}{{group.member}}
    35 | {% endblock %} -------------------------------------------------------------------------------- /Oliver/templates/ywweb/modal.html: -------------------------------------------------------------------------------- 1 | 2 |