├── .gitattributes
├── .idea
├── ApiCaseSystem.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── markdown-navigator.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── ApiCaseSystem
├── .settings.py.swp
├── __init__.py
├── __init__.pyc
├── celery.py
├── celery.pyc
├── hostspage.py
├── settings.py
├── settings.pyc
├── urls.py
├── urls.pyc
├── wsgi.py
└── wsgi.pyc
├── PBS_Dynamic
├── DataCenter.py
├── DataCenter.pyc
├── __init__.py
├── __init__.pyc
├── admin.py
├── admin.pyc
├── apps.py
├── apps.pyc
├── log_obj.py
├── log_obj.pyc
├── media
│ └── introduce_img
│ │ ├── log.gif
│ │ └── wapi.gif
├── migrations
│ ├── __init__.py
│ └── __init__.pyc
├── models.py
├── models.pyc
├── static
│ └── WEB_API
│ │ ├── css
│ │ ├── common
│ │ │ ├── datetimepicker.css
│ │ │ ├── jquery-ui-1.10.4.custom.css
│ │ │ ├── jquery-ui-1.10.4.custom.min.css
│ │ │ ├── jquery-ui.css
│ │ │ ├── jquery-ui.min.css
│ │ │ ├── jquery-ui.structure.css
│ │ │ ├── jquery-ui.structure.min.css
│ │ │ ├── jquery-ui.theme.css
│ │ │ ├── jquery-ui.theme.min.css
│ │ │ └── paging.css
│ │ ├── log
│ │ │ └── check_log.css
│ │ └── wapi_bootstrap
│ │ │ └── bootstrap.min.css
│ │ └── js
│ │ ├── common
│ │ ├── datetimepicker.js
│ │ ├── jquery-1.10.2.js
│ │ ├── jquery-ui-1.10.4.custom.js
│ │ ├── jquery-ui-1.10.4.custom.min.js
│ │ ├── jquery-ui.js
│ │ ├── jquery-ui.min.js
│ │ ├── jquery.min.js
│ │ ├── paging.js
│ │ └── paging.min.js
│ │ ├── log
│ │ └── check_log.js
│ │ └── wapi_bootstrap
│ │ ├── bootstrap.min.js
│ │ └── popper.min.js
├── tasks.py
├── templates
│ └── WEB_API
│ │ ├── log
│ │ ├── check_log.html
│ │ └── tmp.html
│ │ └── report
│ │ ├── index_ignite.html
│ │ └── report.html
├── tests.py
├── views.py
├── views.pyc
├── web_api_forms.py
├── web_api_forms.pyc
├── web_api_paging.py
└── web_api_paging.pyc
├── README.md
├── SOAP_API
├── __init__.py
├── __init__.pyc
├── admin.py
├── admin.pyc
├── apps.py
├── apps.pyc
├── migrations
│ ├── __init__.py
│ └── __init__.pyc
├── models.py
├── models.pyc
├── soap_api_forms.py
├── soap_api_forms.pyc
├── tests.py
└── views.py
├── WingOn
├── .idea
│ ├── WingOn.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── workspace.xml
├── FightDataAndloadCase
│ ├── ProcessData.py
│ ├── ProcessData.pyc
│ ├── StructureData.py
│ ├── StructureData.pyc
│ ├── __init__.py
│ └── __init__.pyc
├── Main.py
├── Main.pyc
├── __init__.py
├── __init__.pyc
├── generateReport
│ ├── HtmlReport.py
│ ├── HtmlReport.pyc
│ ├── IgniteTemplateHtml.py
│ ├── IgniteTemplateHtml.pyc
│ ├── TemplateHtml.py
│ ├── TemplateHtml.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ └── clickA.js
├── methods
│ ├── HttpEntity.py
│ ├── HttpEntity.pyc
│ ├── __init__.py
│ └── __init__.pyc
├── reports
│ ├── click.js
│ ├── igniteReport
│ │ └── ProdFBSFerry点火测试2017_12_28_08_30.html
│ └── reportResult
│ │ └── Prod2018_01_02_11_07.html
└── requestBody
│ ├── Check.py
│ ├── Check.pyc
│ ├── InterfaceCase.py
│ ├── InterfaceCase.pyc
│ ├── RMQ
│ ├── RMQrecive.py
│ ├── RMQsend.py
│ ├── RMQsend.pyc
│ ├── Rsa_encrypt
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── js.py
│ │ ├── js.pyc
│ │ └── rsa.js
│ ├── __init__.py
│ └── __init__.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ └── rsa.js
├── celerybeat.pid
├── manage.py
├── requirements.txt
├── static
├── WEB_API
│ ├── css
│ │ ├── common
│ │ │ ├── datetimepicker.css
│ │ │ ├── jquery-ui-1.10.4.custom.css
│ │ │ ├── jquery-ui-1.10.4.custom.min.css
│ │ │ ├── jquery-ui.css
│ │ │ ├── jquery-ui.min.css
│ │ │ ├── jquery-ui.structure.css
│ │ │ ├── jquery-ui.structure.min.css
│ │ │ ├── jquery-ui.theme.css
│ │ │ ├── jquery-ui.theme.min.css
│ │ │ ├── paging.css
│ │ │ └── paging.less
│ │ ├── log
│ │ │ ├── check_log.css
│ │ │ ├── jquery-ui-1.10.4.custom.css
│ │ │ ├── jquery-ui-1.10.4.custom.min.css
│ │ │ ├── jquery-ui.css
│ │ │ ├── jquery-ui.min.css
│ │ │ ├── jquery-ui.structure.css
│ │ │ ├── jquery-ui.structure.min.css
│ │ │ ├── jquery-ui.theme.css
│ │ │ └── jquery-ui.theme.min.css
│ │ └── wapi_bootstrap
│ │ │ └── bootstrap.min.css
│ └── js
│ │ ├── common
│ │ ├── datetimepicker.js
│ │ ├── jquery-1.10.2.js
│ │ ├── jquery-ui-1.10.4.custom.js
│ │ ├── jquery-ui-1.10.4.custom.min.js
│ │ ├── jquery-ui.js
│ │ ├── jquery-ui.min.js
│ │ ├── jquery.min.js
│ │ ├── paging.js
│ │ └── paging.min.js
│ │ ├── log
│ │ ├── check_log.js
│ │ ├── jquery-1.10.2.js
│ │ ├── jquery-ui-1.10.4.custom.js
│ │ ├── jquery-ui-1.10.4.custom.min.js
│ │ ├── jquery-ui.js
│ │ └── jquery-ui.min.js
│ │ └── wapi_bootstrap
│ │ ├── bootstrap.min.js
│ │ └── popper.min.js
├── admin
│ ├── css
│ │ ├── base.css
│ │ ├── changelists.css
│ │ ├── dashboard.css
│ │ ├── fonts.css
│ │ ├── forms.css
│ │ ├── login.css
│ │ ├── rtl.css
│ │ └── widgets.css
│ ├── fonts
│ │ ├── LICENSE.txt
│ │ ├── README.txt
│ │ ├── Roboto-Bold-webfont.woff
│ │ ├── Roboto-Light-webfont.woff
│ │ └── Roboto-Regular-webfont.woff
│ ├── img
│ │ ├── LICENSE
│ │ ├── README.txt
│ │ ├── calendar-icons.svg
│ │ ├── gis
│ │ │ ├── move_vertex_off.svg
│ │ │ └── move_vertex_on.svg
│ │ ├── icon-addlink.svg
│ │ ├── icon-alert.svg
│ │ ├── icon-calendar.svg
│ │ ├── icon-changelink.svg
│ │ ├── icon-clock.svg
│ │ ├── icon-deletelink.svg
│ │ ├── icon-no.svg
│ │ ├── icon-unknown-alt.svg
│ │ ├── icon-unknown.svg
│ │ ├── icon-yes.svg
│ │ ├── inline-delete.svg
│ │ ├── search.svg
│ │ ├── selector-icons.svg
│ │ ├── sorting-icons.svg
│ │ ├── tooltag-add.svg
│ │ └── tooltag-arrowright.svg
│ └── js
│ │ ├── SelectBox.js
│ │ ├── SelectFilter2.js
│ │ ├── actions.js
│ │ ├── actions.min.js
│ │ ├── admin
│ │ ├── DateTimeShortcuts.js
│ │ └── RelatedObjectLookups.js
│ │ ├── calendar.js
│ │ ├── cancel.js
│ │ ├── change_form.js
│ │ ├── collapse.js
│ │ ├── collapse.min.js
│ │ ├── core.js
│ │ ├── inlines.js
│ │ ├── inlines.min.js
│ │ ├── jquery.init.js
│ │ ├── popup_response.js
│ │ ├── prepopulate.js
│ │ ├── prepopulate.min.js
│ │ ├── prepopulate_init.js
│ │ ├── timeparse.js
│ │ ├── urlify.js
│ │ └── vendor
│ │ ├── jquery
│ │ ├── LICENSE-JQUERY.txt
│ │ ├── jquery.js
│ │ └── jquery.min.js
│ │ └── xregexp
│ │ ├── LICENSE-XREGEXP.txt
│ │ ├── xregexp.js
│ │ └── xregexp.min.js
└── djcelery
│ └── style.css
├── templates
└── hostconfig.html
└── test_django.sql
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css linguist-language=Python
2 | *.js linguist-language=Python
3 | *.html linguist-language=Python
--------------------------------------------------------------------------------
/.idea/ApiCaseSystem.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
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 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ApiCaseSystem/.settings.py.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/.settings.py.swp
--------------------------------------------------------------------------------
/ApiCaseSystem/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals
2 |
3 | # This will make sure the app is always imported when
4 | # Django starts so that shared_task will use this app.
5 | from .celery import app as celery_app
6 |
7 | __all__ = ['celery_app']
--------------------------------------------------------------------------------
/ApiCaseSystem/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/__init__.pyc
--------------------------------------------------------------------------------
/ApiCaseSystem/celery.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals
2 | import os
3 | from celery import Celery, platforms
4 | from django.conf import settings
5 |
6 | # set the default Django settings module for the 'celery' program.
7 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ApiCaseSystem.settings')
8 |
9 | app = Celery('ApiCaseSystem')
10 |
11 | # Using a string here means the worker don't have to serialize
12 | # the configuration object to child processes.
13 | # - namespace='CELERY' means all celery-related configuration keys
14 | # should have a `CELERY_` prefix.
15 | app.config_from_object('django.conf:settings')
16 |
17 | # Load task modules from all registered Django app configs.
18 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
19 |
20 | platforms.C_FORCE_ROOT = True
21 |
22 |
23 | @app.task(bind=True)
24 | def debug_task(self):
25 | print('Request: {0!r}'.format(self.request))
26 |
--------------------------------------------------------------------------------
/ApiCaseSystem/celery.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/celery.pyc
--------------------------------------------------------------------------------
/ApiCaseSystem/hostspage.py:
--------------------------------------------------------------------------------
1 | import time,platform,os
2 | from django.shortcuts import render_to_response
3 | from django.views.decorators.csrf import csrf_exempt
4 |
5 | hostsfile = '/etc/hosts'
6 |
7 |
8 | def basepage(request, issuccess=0):
9 | now = time.strftime('%Y-%m-%d %X', time.localtime())
10 | with open(hostsfile) as f:
11 | hostsconent = f.read()
12 | return render_to_response('hostconfig.html', {'text': hostsconent, 'info': issuccess, 'now': now})
13 |
14 |
15 | @csrf_exempt
16 | def hostupdate(request):
17 | if request.POST.has_key('save'):
18 | contents = request.POST['content'].encode('utf-8')
19 | with open(hostsfile,'w+') as f:
20 | f.write(contents.replace('\r', ''))
21 | issuccess = 1
22 | elif request.POST.has_key('saveandfresh'):
23 | contents = request.POST['content'].encode('utf-8')
24 | with open(hostsfile,'w+') as f:
25 | f.write(contents.replace('\r', ''))
26 | if platform.system() == 'Windows':
27 | os.system('ipconfig /flushdns')
28 | elif platform.system() == 'Linux':
29 | os.system('systemctl restart network')
30 | issuccess = 1
31 | else:
32 | issuccess = 0
33 | return basepage(request, issuccess)
34 |
35 |
--------------------------------------------------------------------------------
/ApiCaseSystem/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for ApiCaseSystem project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.11.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.11/ref/settings/
11 | """
12 |
13 | import os
14 | import platform
15 |
16 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
17 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 |
19 | # DEFAULT_CHARSET = UTF-8
20 |
21 | # Quick-start development settings - unsuitable for production
22 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
23 |
24 | # SECURITY WARNING: keep the secret key used in production secret!
25 | SECRET_KEY = '^(8a(lacnu+)x-1%3^*zo(cy2!adsuq80xvy^+psz(ec(hkyij'
26 |
27 | # SECURITY WARNING: don't run with debug turned on in production!
28 | DEBUG = True
29 |
30 | ALLOWED_HOSTS = ['*']
31 |
32 | # setting django
33 | BROKER_URL = 'django://localhost:8000//'
34 | CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
35 |
36 | if platform.system() == "Windows":
37 | DATABASES = {
38 | 'default': {
39 | 'ENGINE': 'django.db.backends.mysql',
40 | 'NAME': 'xxxxx', # config you database name
41 | 'USER': 'xxx', # database user name
42 | 'PASSWORD': 'xxx', # database pwd
43 | 'HOST': 'xxxx', # database host
44 | 'PORT': 'xxx', # database port
45 | 'OPTIONS': {'charset': 'utf8mb4'},
46 | }
47 | }
48 | CELERY_TIMEZONE = 'UTC' # windows
49 | TIME_ZONE = 'UTC' # windows
50 | else:
51 | DATABASES = {
52 | 'default': {
53 | 'ENGINE': 'django.db.backends.mysql',
54 | 'NAME': 'xxxxx', # config you database name
55 | 'USER': 'xxx', # database user name
56 | 'PASSWORD': 'xxx', # database pwd
57 | 'HOST': 'xxxx', # database host
58 | 'PORT': 'xxx', # database port
59 | 'OPTIONS': {'charset': 'utf8mb4'},
60 | }
61 | }
62 | CELERY_TIMEZONE = 'Asia/Shanghai' # 191 linux
63 | TIME_ZONE = 'Asia/Shanghai' # 191 LINUX
64 |
65 |
66 | # Application definition
67 |
68 | INSTALLED_APPS = [
69 | # 'bootstrap_admin',
70 | 'django.contrib.admin',
71 | 'django.contrib.auth',
72 | 'django.contrib.contenttypes',
73 | 'django.contrib.sessions',
74 | 'django.contrib.messages',
75 | 'django.contrib.staticfiles',
76 | 'kombu.transport.django',
77 | 'djcelery.app.DjceleryConf',
78 | # 'djcelery',
79 | # 'djkombu',
80 | 'PBS_Dynamic',
81 | 'SOAP_API',
82 | # 'PBS_Dynamic.apps.PbsDynamicConfig',
83 |
84 |
85 | ]
86 |
87 | MIDDLEWARE = [
88 | 'django.middleware.security.SecurityMiddleware',
89 | 'django.contrib.sessions.middleware.SessionMiddleware',
90 | 'django.middleware.common.CommonMiddleware',
91 | 'django.middleware.csrf.CsrfViewMiddleware',
92 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
93 | 'django.contrib.messages.middleware.MessageMiddleware',
94 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
95 | ]
96 |
97 | ROOT_URLCONF = 'ApiCaseSystem.urls'
98 |
99 | TEMPLATES = [
100 | {
101 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
102 | 'DIRS': [os.path.join(BASE_DIR, 'templates')],
103 | 'APP_DIRS': True,
104 | 'OPTIONS': {
105 | 'context_processors': [
106 | 'django.template.context_processors.debug',
107 | 'django.template.context_processors.request',
108 | 'django.contrib.auth.context_processors.auth',
109 | 'django.contrib.messages.context_processors.messages',
110 | ],
111 | },
112 | },
113 | ]
114 |
115 | WSGI_APPLICATION = 'ApiCaseSystem.wsgi.application'
116 |
117 |
118 | # Database
119 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
120 |
121 | # DATABASES = {
122 | # 'default': {
123 | # 'ENGINE': 'django.db.backends.sqlite3',
124 | # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
125 | # }
126 | # }
127 |
128 | # Password validation
129 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
130 |
131 | AUTH_PASSWORD_VALIDATORS = [
132 | {
133 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
134 | },
135 | {
136 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
137 | },
138 | {
139 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
140 | },
141 | {
142 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
143 | },
144 | ]
145 |
146 |
147 | # Internationalization
148 | # https://docs.djangoproject.com/en/1.11/topics/i18n/
149 |
150 | LANGUAGE_CODE = 'zh-Hans'
151 |
152 | # LANGUAGE_CODE = 'en-us'
153 |
154 | USE_I18N = True
155 |
156 | # USE_L10N = True
157 | USE_L10N = False
158 | DATETIME_FORMAT = 'Y-m-d H:i:s'
159 | DATE_FORMAT = 'Y-m-d'
160 |
161 | # USE_TZ = True
162 | USE_TZ = False
163 |
164 |
165 | # Static files (CSS, JavaScript, Images)
166 | # https://docs.djangoproject.com/en/1.11/howto/static-files/
167 |
168 | STATIC_URL = '/static/'
169 |
170 | STATIC_ROOT = os.path.join(BASE_DIR, 'static')
171 |
172 |
--------------------------------------------------------------------------------
/ApiCaseSystem/settings.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/settings.pyc
--------------------------------------------------------------------------------
/ApiCaseSystem/urls.py:
--------------------------------------------------------------------------------
1 | """ApiCaseSystem URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.11/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. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf.urls import url
17 | from django.contrib import admin
18 | from PBS_Dynamic import views
19 |
20 | urlpatterns = [
21 | url(r'^admin/', admin.site.urls),
22 | url(r'^log/$', views.log),
23 | # url('^hostupdate/$', hostupdate),
24 | ]
25 |
--------------------------------------------------------------------------------
/ApiCaseSystem/urls.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/urls.pyc
--------------------------------------------------------------------------------
/ApiCaseSystem/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for ApiCaseSystem 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.11/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | # import sys
12 |
13 | from django.core.wsgi import get_wsgi_application
14 |
15 | # sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
16 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ApiCaseSystem.settings")
17 |
18 | application = get_wsgi_application()
19 |
--------------------------------------------------------------------------------
/ApiCaseSystem/wsgi.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/ApiCaseSystem/wsgi.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/DataCenter.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | class Common:
5 | """
6 | 单执行Rest/Web Api用例字段信息等
7 | """
8 | def __init__(self):
9 | self.list_id = []
10 | self.start_time = None
11 | self.use_time = None
12 | self.user = None
13 | self.environment = None
14 | self.methods = 'test_case'
15 | self.suite_name = ''
16 | self.case_id_list = []
17 | self.system_type = []
18 | self.email_list = []
19 | self.pattern_list = []
20 | self.content_list = []
21 | self.api_type_list = []
22 | self.api_type = 0
23 | self.use_time_list = []
24 |
25 |
26 | class SuiteDataCenter:
27 | """
28 | 执行测试套件信息
29 | """
30 | def __init__(self):
31 | self.list_id = []
32 | self.start_time = None
33 | self.use_time = []
34 | self.user = None
35 | self.environment = None
36 | self.methods = 'test_suite'
37 | self.suite_name = []
38 | self.case_id_list = []
39 | self.system_type = []
40 | self.email_list = []
41 | self.pattern_list = []
42 | self.content_list = []
43 | self.api_type_list = []
44 | self.api_type = None
45 | self.use_time_list = []
46 |
47 |
48 | class SoapDataCenter:
49 | """
50 | 单执行Soap Api测试套件信息
51 | """
52 | def __init__(self):
53 | self.list_id = []
54 | self.start_time = None
55 | self.use_time = None
56 | self.user = None
57 | self.environment = None
58 | self.methods = 'test_case'
59 | self.suite_name = ''
60 | self.case_id_list = []
61 | self.system_type = []
62 | self.email_list = []
63 | self.pattern_list = []
64 | self.content_list = []
65 | self.api_type_list = []
66 | self.api_type = 1
67 | self.use_time_list = []
68 |
69 |
70 | class IgniteDataCenter:
71 | """
72 | 点火系统 信息
73 | """
74 | def __init__(self):
75 | self.list_id = []
76 | self.methods = 'ignite'
77 | self.environment = None
78 | self.environ = None
79 | self.system_type_list = []
80 | self.system_name_list = []
81 | self.start_time = None
82 | self.use_time = None
83 | self.user = None
84 | self.file_h = '.html'
85 | self.api_type = 0
86 | self.use_time_list = []
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/PBS_Dynamic/DataCenter.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/DataCenter.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/__init__.py:
--------------------------------------------------------------------------------
1 | default_app_config = 'PBS_Dynamic.apps.PbsDynamicConfig'
2 |
--------------------------------------------------------------------------------
/PBS_Dynamic/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/__init__.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/admin.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/admin.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class PbsDynamicConfig(AppConfig):
8 | name = u'PBS_Dynamic'
9 | verbose_name = 'WEB/REST接口测试用例管理系统'
10 |
--------------------------------------------------------------------------------
/PBS_Dynamic/apps.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/apps.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/log_obj.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | class LogObj(object):
5 |
6 | def __init__(self):
7 | self.check_result = None
8 | self.case_type = 0
9 | self.case_id = ''
10 | self.sub_case_id = ''
11 | self.click_time = None
12 | self.end_time = None
13 | self.system = ''
14 | self.environment = ''
15 | self.click_time = None
16 | self.end_time = None
17 | self.start_index = 0
18 | self.end_index = 15
19 | self.token = None
20 | self.page_url = None
21 | self.api_type = None
22 | self.soap_system = ''
23 |
24 | # def start_indexa(self):
25 | # start_index = self.start_index
26 | # return start_index
27 | #
28 | # def end_indexa(self):
29 | # end_index = self.end_index
30 | # return end_index
31 | #
32 | # def check_resultzz(self):
33 | # check_result = self.check_result
34 | # return check_result
35 | #
36 | # def page_urlz(self):
37 | # page_url = self.page_url
38 | # return page_url
39 | #
40 | # def click_times(self):
41 | # click_time = self.click_time
42 | # return click_time
43 | #
44 | # def end_times(self):
45 | # end_time = self.click_time
46 | # return end_time
--------------------------------------------------------------------------------
/PBS_Dynamic/log_obj.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/log_obj.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/media/introduce_img/log.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/media/introduce_img/log.gif
--------------------------------------------------------------------------------
/PBS_Dynamic/media/introduce_img/wapi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/media/introduce_img/wapi.gif
--------------------------------------------------------------------------------
/PBS_Dynamic/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/migrations/__init__.py
--------------------------------------------------------------------------------
/PBS_Dynamic/migrations/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/migrations/__init__.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/models.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/models.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/static/WEB_API/css/common/paging.css:
--------------------------------------------------------------------------------
1 | #box{list-style:none;margin:0;padding:0;margin-left:2%;margin-top:1%;}
2 | #box li {
3 | color: #0084F3;
4 | text-align: center;
5 | width: 60px;
6 | height: 40px;
7 | border: 1px solid #ebebeb;
8 | line-height: 40px;
9 | box-sizing: border-box;
10 | cursor: pointer;
11 | float: left;
12 | }
13 | #box li a{
14 | display:block;
15 | width: 60px;
16 | height: 40px;
17 | line-height: 40px;
18 | }
19 | #box .active{background: #0084F3}
20 | #box .active a{color: white;}
21 | #box li a{text-decoration:none;}
22 | #box span{margin-left: 20px;height: 40px;line-height: 40px;}
--------------------------------------------------------------------------------
/PBS_Dynamic/static/WEB_API/css/log/check_log.css:
--------------------------------------------------------------------------------
1 | #loading{width:100%;height:100%;background:#000;opacity:0;
2 | position:absolute;top:0px;color:white;z-index:50;
3 | font-size:36px;font-family:'微软雅黑';text-align:center;padding-top:25%;
4 | -webkit-transition:all 2s;display:none;}
5 | #mainview{
6 | width: 90%;margin-top: 1%;margin-left:5%;
7 | -moz-box-shadow: 0 0 5px;/*firefox*/
8 | -webkit-box-shadow: 0 0 5px;/*webkit*/
9 | box-shadow: 0 0 5px;/*opera或ie9*/
10 | -moz-border-radius:5px;
11 | -webkit-border-radius:5px;
12 | border-radius: 5px;
13 | padding: 5px;}
14 | #tarTop{
15 | text-align: center; background: #0084F3;
16 | height: 3%;
17 | font-family: '微软雅黑';font-size: 24px;font-weight: bold;line-height: 40px;color: white;
18 | -moz-box-shadow: 0 0 3px;
19 | -webkit-box-shadow: 0 0 3px;
20 | box-shadow: 0 0 3px;
21 | -moz-border-radius: 5px;
22 | -webkit-border-radius: 5px;
23 | border-radius: 5px; }
24 | /*40px=3%*/
25 | #oform{ margin-top: 1.5%; }
26 | #input_div{margin-left:1%;width: 98%;}
27 | #sel{width: 10%;}
28 | #click_time{width: 12%;}
29 | #end_time{width: 12%;}
30 | /*restapi 系统选择*/
31 | #systemcode{width: 15%;font-size: 18px;}
32 | /*soapapi 系统选择*/
33 | #soap_system_code{width: 15.7%;font-size: 16px;}
34 |
35 | #enviorment{width: 10%;}
36 | #case_id{width: 8%;height: 37px;}
37 | #sub_case_id{width: 8%;}
38 | #submit_btn{width:5%;background:#0084F3;color:white;margin-left:5%}
39 | #submit_btn:hover{opacity:0.6;}
40 |
41 |
42 |
43 | #search_thread{margin: 0 auto;margin-top: 2%;height:40px;background: #11A0FF; color: white; font-weight: bold; border-radius: 5px;}
44 | #search_thread table{width:97%; height:100%;text-align: left;margin-left: 2%;border-collapse: separate;}
45 | /*#search_thread table tr td{background: red}
46 | .div_title table tr td{background: black;}*/
47 | /*开始执行时间*/
48 | #search_thread .ClickExecutionTime2{width:15.5%;}
49 | /*接口名称*/
50 | #search_thread .testCase__ApiName2{width: 33%;}
51 | /*描述*/
52 | #search_thread .testCase__Description2{width: 21.6%;}
53 | /*ID*/
54 | #search_thread .testCase_id2{width: 5%;}
55 | /*执行步骤*/
56 | #search_thread .testCase__SetupStep2{width: 11%;}
57 | /*环境*/
58 | #search_thread .Environment2{width: 5%;}
59 | /*结果*/
60 | #search_thread .Status2{width: 9%;}
61 | /*子用例使用样式 ID 步骤类型*/
62 | #search_thread .SubCaseID_id2{width: 8%;}
63 | #search_thread .SubCaseID__SetupType2{width: 8%;}
64 |
65 | /* soap 用例样式 testCase_id2*/
66 | #search_thread .soapTestCase_id2{width: 8%;}
67 | #search_thread .soapTestCase__SetupStep2{width: 8%;}
68 | #search_thread .soapSubCase_id2{width: 5%;}
69 |
70 |
71 | /*log内容样式*/
72 | #accordion{--webkit-box-shadow: 0 0 5px; margin-top: 0.5%;}
73 | #accordion div:nth-child(even){display:none;padding:25px;text-align:left;background:#F7F7F7;word-break: break-all;word-wrap:break-word;};
74 | #accordion div:nth-child(odd){height:40px;};
75 | .div_title{border-radius:10px;box-shadow: 0 0 5px #CCCCCC;}
76 | .div_title table{height:40px;border-bottom:1px solid #DDD;width: 97%;margin-left:2%;table-layout: fixed; text-align: left;border-collapse: separate;word-break: break-all; word-wrap: break-word;}
77 | .div_title table tr td{overflow: hidden;text-overflow:ellipsis;white-space: nowrap;}
78 | /*开始执行时间*/
79 | .div_title .ClickExecutionTime{width: 15.5%;}
80 | /*接口名称*/
81 | .div_title .testCase__ApiName,.SubCaseID__ApiName{width: 33%;}
82 | /*描述*/
83 | .div_title .testCase__Description,.SubCaseID__Description{width: 21.6%;}
84 | /*ID*/
85 | .div_title .testCase_id,.SubCaseID_id{width: 5%;}
86 | .div_title .SubCaseID_id{width: 8%;}
87 | /*执行步骤||步骤类型*/
88 | .div_title .testCase__SetupStep,.SubCaseID__SetupType{width: 11%;}
89 | .div_title .SubCaseID__SetupType{width: 8%;}
90 | /*环境*/
91 | .div_title .Environment{width: 5%;}
92 | /*结果状态*/
93 | .div_title .Status{ width: 9%; color:#6c6; font-weight:bold;}
94 |
95 | /* soap 主用例样式 testCase_id2*/
96 | .div_title .soapSubCase_id{width: 5%;}
97 | .div_title .soapTestCase_id{width: 8%;}
98 |
99 | .div_title .soapTestCase__Description,.soapSubCase__Description{width: 21.6%;}
100 | .div_title .soapTestCase__SetupStep,.soapSubCase__SetupType{width: 8%;}
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/PBS_Dynamic/static/WEB_API/js/common/paging.min.js:
--------------------------------------------------------------------------------
1 | (function(d, c, a) {
2 | function b(f, e) {
3 | this.el = f;
4 | this.options = { pageNo: e.initPageNo || 1, totalPages: e.totalPages || 1, totalCount: e.totalCount || "", slideSpeed: e.slideSpeed || 0, jump: e.jump || false, callback: e.callback || function() {} };
5 | this.init()
6 | }
7 | b.prototype = {
8 | constructor: b,
9 | init: function() {
10 | this.createDom();
11 | this.bindEvents()
12 | },
13 | createDom: function() {
14 | var k = this,
15 | m = "",
16 | e = "",
17 | j = "",
18 | g = 60,
19 | h = k.options.totalPages,
20 | l = 0;
21 | h > 5 ? l = 5 * g : l = h * g;
22 | for (var f = 1; f <= k.options.totalPages; f++) { f != 1 ? m += "
" + f + " " : m += '' + f + " " }
23 | k.options.jump ? e = '跳转 ' : e = "";
24 | j = '首页 ' + '上一页 ' + '" + '下一页 ' + '尾页 ' + e + '共 ' + k.options.totalPages + " 页
" + '' + k.options.totalCount + "
";
25 | k.el.html(j)
26 | },
27 | bindEvents: function() {
28 | var k = this,
29 | f = d("#pageSelect"),
30 | r = f.children(),
31 | n = r[0].offsetWidth,
32 | l = k.options.totalPages,
33 | g = k.options.pageNo,
34 | e = 0,
35 | o = d("#prePage"),
36 | m = d("#nextPage"),
37 | i = d("#firstPage"),
38 | j = d("#lastPage"),
39 | q = d("#jumpBtn"),
40 | h = d("#jumpText");
41 | o.on("click", function() {
42 | g--;
43 | if (g < 1) { g = 1 }
44 | p(g)
45 | });
46 | m.on("click", function() {
47 | g++;
48 | if (g > r.length) { g = r.length }
49 | p(g)
50 | });
51 | i.on("click", function() {
52 | g = 1;
53 | p(g)
54 | });
55 | j.on("click", function() {
56 | g = l;
57 | p(g)
58 | });
59 | q.on("click", function() {
60 | var s = parseInt(h.val().replace(/\D/g, ""));
61 | if (s && s >= 1 && s <= l) {
62 | g = s;
63 | p(g);
64 | h.val(s)
65 | }
66 | });
67 | r.on("click", function() {
68 | g = d(this).index() + 1;
69 | p(g)
70 | });
71 |
72 | function p(s) {
73 | r.removeClass("sel-page").eq(s - 1).addClass("sel-page");
74 | if (l <= 5) { k.options.callback(s); return false }
75 | if (s >= 3 && s <= l - 2) { e = (s - 3) * n }
76 | if (s == 2 || s == 1) { e = 0 }
77 | if (s > l - 2) { e = (l - 5) * n }
78 | f.css("transform", "translateX(" + (-e) + "px)");
79 | s == 1 ? i.attr("disabled", true) : i.attr("disabled", false);
80 | s == 1 ? o.attr("disabled", true) : o.attr("disabled", false);
81 | s == l ? j.attr("disabled", true) : j.attr("disabled", false);
82 | s == l ? m.attr("disabled", true) : m.attr("disabled", false);
83 | k.options.callback(s)
84 | }
85 | p(k.options.pageNo)
86 | }
87 | };
88 | d.fn.paging = function(e) { return new b(d(this), e) }
89 | })(jQuery, window, document);
--------------------------------------------------------------------------------
/PBS_Dynamic/static/WEB_API/js/log/check_log.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | $('#sub_case_id').attr("disabled","disabled");
3 | $('#soap_system_code').css('display','none');
4 | });
5 | //主用例/子用例切换响应事件
6 | function chg(){
7 | if(document.getElementById("sel").value=="0"){
8 |
9 | $('#sub_case_id').attr("disabled","disabled");
10 | $('#sub_case_id').val('');
11 | }
12 | else{
13 | $('#sub_case_id').removeAttr("disabled");
14 | $('#sub_case_id').val('');
15 |
16 | }
17 | };
18 |
19 | //SoapAPI/RestAPI切换响应事件
20 | function changeType(){
21 | if(document.getElementById("api_type").value=="SoapAPI"){
22 | document.getElementById("soap_system_code").style.display='';
23 | document.getElementById("system_code").style.display='none';
24 | }else{
25 | document.getElementById("soap_system_code").style.display='none';
26 | document.getElementById("system_code").style.display='';
27 | }
28 | }
29 | $(function() {
30 | $( "#click_time" ).datetimepicker({
31 | format:'Y-m-d H:i:s',
32 | step:10
33 | });
34 | $( "#end_time" ).datetimepicker({
35 | format:'Y-m-d H:i:s',
36 | step:10
37 | });
38 | });
39 |
40 |
41 | //日志详情展开 方法
42 | function logSlideToggle(){
43 | $(".div_title").click(function(){
44 | $(this).next().slideToggle();
45 | });
46 | }
47 | //状态颜色 方法
48 | function statusColor(){
49 | var table_content=$('.table_content');
50 | var i=0;
51 | for( var i = 0; i < table_content.length; i++ ) {
52 |
53 | var result_td=table_content.eq(i).children("td:last-child");
54 | if(result_td.html()=='Fail'){
55 | result_td.css('color','#c60');
56 | }
57 | else if(result_td.html()=='Error'){
58 | result_td.css('color','#c00');
59 | }
60 | else if(result_td.html()=='Success'){
61 | result_td.css('color','#6c6');
62 | }else{
63 | ;
64 | }
65 | }
66 | }
67 | //分页链接 点击响应 方法
68 | function linkClick(){
69 | $('a').click(function(){
70 | var oLink=$(this).attr('href');
71 | //alert(oLink);
72 | $.ajax({
73 | url: oLink,
74 | success: function(result, statues, xml){
75 | //alert('进入分页回调');
76 | //alert(result);
77 | $("#response_result").html(result);
78 | logSlideToggle();
79 | statusColor();
80 | linkClick();
81 | },
82 | error: function(){
83 | alert("false");
84 | },
85 | dataType: "html"
86 | });
87 | return false;
88 | });
89 | }
90 | //页面加载完成 方法 查询提交请求
91 | $(document).ready(function(){
92 | $.ajaxSetup({
93 | data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
94 | });
95 | //查询提交 get请求
96 | $('#submit_btn').click(function(){
97 | //alert('进入submit');
98 | var csrfmiddlewaretoken='{{ csrf_token }}';
99 | var api_type = $("#api_type").val();
100 | var case_type = $("#sel").val();
101 | var click_time = $("#click_time").val();
102 | var end_time = $("#end_time").val();
103 | var system_code = $("#system_code").val();
104 | var soap_system_code = $("#soap_system_code").val();
105 | var environment = $("#environment").val();
106 | var case_id = $("#case_id").val();
107 | var sub_case_id = $("#sub_case_id").val();
108 | //正整数正则表达式 1-9开头
109 | var reg=/^[1-9]\d*$|^0$/;
110 | if(click_time==''||end_time==''){
111 | alert('开始时间和结束时间不能为空');
112 | $("#click_time").focus();
113 | return false;
114 | }else if(click_time>end_time){
115 | alert('开始时间不能早于结束时间');
116 | $("#click_time").focus();
117 | return false;
118 | }else if(case_type=='1'&&(case_id&&!(sub_case_id)||(sub_case_id&&(!case_id)))){
119 | if(case_id&&!(sub_case_id)){alert('有主用例ID时 必须输入子用例ID');$("#sub_case_id").focus();}
120 | else{alert('有子用例ID时 必须输入主用例ID');$("#case_id").focus();}
121 | return false;
122 | }else if(case_type=='1'&&!(!case_id&&!sub_case_id)&&(reg.test(case_id)==false||reg.test(sub_case_id)==false)){
123 | alert('请输入正确的ID');
124 | return false;
125 | }else if(case_type=='0'&&case_id&®.test(case_id)==false){
126 | alert('请输入正确的主用例ID');
127 | $("#case_id").focus();
128 | return false;
129 | }
130 | else{
131 | document.getElementById("loading").style.display='block';
132 | document.getElementById("loading").style.opacity='0.6';
133 | $.ajax({
134 | type:"GET",
135 | data: {api_type:api_type,case_type:case_type,click_time:click_time,
136 | end_time:end_time,system_code:system_code,soap_system_code:soap_system_code,
137 | environment:environment,case_id:case_id,sub_case_id:sub_case_id},
138 | url: "/log/",
139 | cache: false,
140 | dataType: "html",
141 | /*ajax成功时回调方法*/
142 | success: function(result, statues, xml){
143 | //关闭 loading
144 | document.getElementById("loading").style.display='none';
145 | //局部刷新数据
146 | $("#response_result").html(result);
147 | //加载分页提交事件
148 | linkClick();
149 | //加载数据下拉事件
150 | logSlideToggle();
151 | //加载状态颜色事件
152 | statusColor();
153 | },
154 | error: function(){
155 | alert("false");
156 | }
157 | });
158 | return false;
159 | }
160 | });
161 | });
162 |
--------------------------------------------------------------------------------
/PBS_Dynamic/templates/WEB_API/log/tmp.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 用例开始时间
5 | 用例中文描述
6 | {% ifequal api_type 'RestAPI' %}
7 | 接口名称
8 | {% ifequal case_type 1 %}
9 | ID
10 | 步骤类型
11 | 环境
12 | {% else %}
13 | ID
14 | 子用例步骤
15 | 环境
16 | 结果
17 | {% endifequal %}
18 | {% else %}
19 | {% ifequal case_type 1 %}
20 | ID
21 | 步骤类型
22 | 环境
23 | {% else %}
24 | ID
25 | 子用例步骤
26 | 环境
27 | 结果
28 | {% endifequal %}
29 | {% endifequal %}
30 |
31 |
32 |
33 |
34 |
35 |
36 | {% for result_node in result %}
37 | {% ifequal api_type 'RestAPI' %}
38 | {% ifequal case_type 0 %}
39 |
40 |
41 |
42 | {{ result_node.ClickExecutionTime }}
43 | {{ result_node.testCase__Description }}
44 | {{ result_node.testCase__ApiName }}
45 | {{ result_node.testCase_id }}
46 | {{ result_node.testCase__SetupStep }}
47 | {{ result_node.Environment }}
48 | {{ result_node.Status }}
49 |
50 |
51 |
52 |
53 | {% else %}
54 |
55 |
56 |
57 | {{ result_node.ClickExecutionTime }}
58 | {{ result_node.SubCaseID__Description }}
59 | {{ result_node.SubCaseID__ApiName }}
60 | {{ result_node.SubCaseID_id }}
61 | {{ result_node.SubCaseID__SetupType }}
62 | {{ result_node.Environment }}
63 |
64 |
65 |
66 | {% endifequal %}
67 |
68 |
{{ result_node.APIResult }}
69 |
70 |
71 | {% else %}
72 | {% ifequal case_type 0 %}
73 |
74 |
75 |
76 | {{ result_node.ClickExecutionTime }}
77 |
78 | {{ result_node.soapTestCase__Description }}
79 | {{ result_node.soapTestCase_id }}
80 | {{ result_node.soapTestCase__SetupStep }}
81 | {{ result_node.Environment }}
82 | {{ result_node.Status }}
83 |
84 |
85 |
86 |
87 | {% else %}
88 |
89 |
90 |
91 | {{ result_node.ClickExecutionTime }}
92 |
93 | {{ result_node.soapSubCase__Description }}
94 | {{ result_node.soapSubCase_id }}
95 | {{ result_node.soapSubCase__SetupType }}
96 | {{ result_node.Environment }}
97 |
98 |
99 |
100 | {% endifequal %}
101 |
102 |
{{ result_node.APIResult }}
103 |
104 |
105 |
106 | {% endifequal %}
107 | {% endfor %}
108 |
109 | {{ page_str|safe}}
--------------------------------------------------------------------------------
/PBS_Dynamic/templates/WEB_API/report/index_ignite.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 点火结果报告
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
42 |
43 |
44 |
45 |
46 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | API Automation Description
72 | User: xinglongwang
73 | StartTime: 2017-11-22 09:37:49.427000
74 | UseTime: 0:00:00.080000
75 | Success: 与预期结果校验正确(ExpectResult)
76 | Fail: 与预期结果校验错误(ExpectResult)
77 | Error: 用例格式数据或输入错误
78 |
79 |
80 |
81 |
82 |
83 | Result Count
84 | Total: 0
85 | Status_200: 0
86 | Status_Other: 0
87 |
88 |
89 |
90 |
91 |
92 |
93 | ID
94 | SystemType
95 | ApiName
96 | Method
97 | Status
98 | ExecutionTime
99 | UseTime (S)
100 |
101 |
102 | 1
103 | PBSDynamicH5
104 | /Product/Theme/{ThemeID}
105 | post
106 | 200
107 | 2017-10-31 19:00:57.729257
108 | 0.0177059173584
109 |
110 |
111 | 1
112 | PBSDynamicH5
113 | /Product/Theme/{ThemeID}
114 | post
115 | 200
116 | 2017-10-31 19:00:57.729257
117 | 0.0177059173584
118 |
119 |
120 | 1
121 | PBSDynamicH5
122 | /Product/Theme/{ThemeID}
123 | post
124 | 200
125 | 2017-10-31 19:00:57.729257
126 | 0.0177059173584
127 |
128 |
129 | 1
130 | PBSDynamicH5
131 | /Product/Theme/{ThemeID}
132 | post
133 | 200
134 | 2017-10-31 19:00:57.729257
135 | 0.0177059173584
136 |
137 |
138 | 1
139 | PBSDynamicH5
140 | /Booking/MotoBack4Web/{ProductId}/{TempOrderId}/{PkgOrderNO}
141 | post
142 | 200
143 | 2017-10-31 19:00:57.729257
144 | 0.0177059173584
145 |
146 |
147 | 1
148 | PBSDynamicH5
149 | /Product/Theme/{ThemeID}
150 | post
151 | 500
152 | 2017-10-31 19:00:57.729257
153 | 0.0177059173584
154 |
155 |
156 | 1
157 | PBSDynamicH5
158 | /Product/Theme/{ThemeID}
159 | post
160 | 200
161 | 2017-10-31 19:00:57.729257
162 | 0.0177059173584
163 |
164 |
165 | 1
166 | PBSDynamicH5
167 | /Product/Theme/{ThemeID}
168 | post
169 | 200
170 | 2017-10-31 19:00:57.729257
171 | 0.0177059173584
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/PBS_Dynamic/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/PBS_Dynamic/views.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/views.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/web_api_forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .models import *
3 | from django import forms
4 |
5 |
6 | class TestCaseForm(forms.ModelForm):
7 | """
8 | 定义主用例中的 字段规则,
9 | 默认是必填,required=False(选填)
10 | """
11 | # Host = forms.ChoiceField(label=u'HOST环境路径')
12 | HostName = forms.CharField(label=u'Host环境名', required=False, widget=forms.TextInput(
13 | attrs={'readonly': 'true'}))
14 | Description = forms.CharField(label=u'测试用例描述', widget=forms.Textarea(
15 | attrs={'cols': '85', 'rows': '1'}))
16 |
17 | ApiName = forms.CharField(label=u'接口uri', widget=forms.Textarea(
18 | attrs={'cols': '85', 'rows': '1'}))
19 |
20 | Method = forms.ChoiceField(label=u'方法', choices=[('post', 'post'), ('get', 'get')])
21 |
22 | SetupStep = forms.CharField(label=u'Setup步骤', required=False, widget=forms.Textarea(
23 | attrs={'cols': '85', 'rows': '1'}))
24 |
25 | UrlParameter = forms.CharField(label=u'Url参数', required=False, widget=forms.Textarea(
26 | attrs={'cols': '85', 'rows': '1'}))
27 | # Suite = forms.ChoiceField(label=u'测试套件', choices=[(i.id, i.Name) for i in TestSuite.objects.all()])
28 | Expect = forms.CharField(label=u'预期值', widget=forms.Textarea(
29 | attrs={'cols': '85', 'rows': '1'}))
30 | APIResult = forms.CharField(label=u'API结果', required=False, widget=forms.Textarea(
31 | attrs={'readonly': 'true', 'cols': '85'}))
32 | Status = forms.CharField(label=u'状态', required=False, widget=forms.TextInput(
33 | attrs={'readonly': 'true', 'class': 'vTextField'}))
34 | UseTime = forms.CharField(label=u'接口消耗时间(s)', required=False, widget=forms.TextInput(
35 | attrs={'readonly': 'true', 'class': 'vTextField'}))
36 | ExecutionTime = forms.DateTimeField(label=u'用例执行时间', required=False, widget=forms.TextInput(
37 | attrs={'readonly': 'true', 'class': 'vTextField'}))
38 |
39 | # Suite = forms.ChoiceField(label=u'测试套件')
40 |
41 | # 动态加载下拉表单的数据
42 | def __init__(self, *args, **kwargs):
43 | super(TestCaseForm, self).__init__(*args, **kwargs)
44 | # self.fields['Suite'].choices = ((i.id, i.Name) for i in TestSuite.objects.all())
45 | # self.fields['Host'].choices = ((host.Uri, host.Uri) for host in SystemHost.objects.all())
46 |
47 | class Meta:
48 | forms.model = TestCase
49 |
50 |
51 | class SubTestCaseForm(forms.ModelForm):
52 | """
53 | 定义子用例中的 字段规则,
54 | """
55 | # Host = forms.ChoiceField(label=u'HOST环境路径', choices=[(host[1], host[1]) for host in host_list])
56 | # Host = forms.ChoiceField(label=u'HOST环境路径')
57 | Method = forms.ChoiceField(label=u'方法', choices=[('post', 'post'), ('get', 'get'), ('put', 'put')])
58 | DataBox = forms.CharField(label=u'数据值', widget=forms.Textarea(
59 | attrs={'cols': '72', 'rows': '1'}))
60 | APIResult = forms.CharField(label=u'API结果', required=False, widget=forms.Textarea(
61 | attrs={'readonly': 'true', 'cols': '72'}))
62 | UseTime = forms.CharField(label=u'接口消耗时间(s)', required=False, widget=forms.TextInput(
63 | attrs={'readonly': 'true', 'class': 'vTextField'}))
64 |
65 | HostName = forms.CharField(label=u'Host环境名', required=False, widget=forms.TextInput(
66 | attrs={'readonly': 'true'}))
67 |
68 | ExecutionTime = forms.DateTimeField(label=u'用例执行时间', required=False, widget=forms.TextInput(
69 | attrs={'readonly': 'true', 'class': 'vTextField'}))
70 |
71 | def __init__(self, *args, **kwargs):
72 | super(SubTestCaseForm, self).__init__(*args, **kwargs)
73 | self.fields['Host'].choices = ((host.Uri, host.Uri) for host in SystemHost.objects.all())
74 |
75 | class Meta:
76 | forms.model = SubTestCase
77 |
78 |
79 | class TestSuiteForm(forms.ModelForm):
80 | """
81 | 定义测试套件中 Name字段表单规则
82 | """
83 | Name = forms.CharField(label=u'测试套件名称', validators=[validate_name],
84 | help_text=u'必须输入下划线!如 PBS_H5动态下单流程任务',
85 | widget=forms.Textarea(attrs={'cols': '85', 'rows': '1'})
86 | )
87 |
88 | Description = forms.CharField(label=u'主用例ID內容', validators=[validate_description],
89 | help_text=u'必須是一個 list 且內容是主用例ID 如 [12, 13]',
90 | widget=forms.Textarea(attrs={'cols': '85', 'rows': '10'})
91 | )
92 | # Pattern = forms.ChoiceField(label=u'模式', choices=[('0', '默认不对接'), ('1', '对接运维监控')],)
93 | ApiType = forms.ChoiceField(label=u'API类型', choices=[('REST API', 'REST API'), ('SOAP API', 'SOAP API')],
94 | help_text=u'如选REST API, 主用例ID內容 必须输入是REST API的')
95 |
96 |
97 | class SystemHostForm(forms.ModelForm):
98 | """
99 | 环境系统表单字段规则
100 | """
101 | Uri = forms.CharField(label=u'Host URI 地址', widget=forms.Textarea(attrs={'cols': '72'}))
102 |
103 | class Meta:
104 | forms.model = SystemHost
105 |
106 |
107 | class IgniteForm(forms.ModelForm):
108 | """
109 | 点火中表单字段规则
110 | """
111 | ExecutionTime = forms.DateTimeField(label=u'点火执行时间', required=False, widget=forms.TextInput(
112 | attrs={'readonly': 'true', 'class': 'vTextField'}))
113 | # Host = forms.CharField(label=u'执行状态', help_text='0:执行,1:不执行')
114 |
115 |
116 | class IgniteCommonForm(forms.ModelForm):
117 | """
118 | 点火用例抽象基类表单字段规则
119 | """
120 | SystemType = forms.ChoiceField(label=u'系统类别')
121 | Method = forms.ChoiceField(label=u'方法', choices=[('post', 'post'), ('get', 'get')])
122 | Status = forms.CharField(label=u'状态', required=False, widget=forms.TextInput(
123 | attrs={'readonly': 'true', 'class': 'vTextField'}))
124 | UseTime = forms.CharField(label=u'接口消耗时间(s)', required=False, widget=forms.TextInput(
125 | attrs={'readonly': 'true', 'class': 'vTextField'}))
126 | ExecutionTime = forms.DateTimeField(label=u'执行时间', required=False, widget=forms.TextInput(
127 | attrs={'readonly': 'true', 'class': 'vTextField'}))
128 | ExecuteStatus = forms.CharField(label=u'执行状态', help_text='0:执行,1:不执行')
129 |
130 | def __init__(self, *args, **kwargs):
131 | super(IgniteCommonForm, self).__init__(*args, **kwargs)
132 | self.fields['SystemType'].choices = ((host.SystemType, host.SystemType) for host in SystemHost.objects.all())
133 |
134 |
135 | class UpdateHostForm(forms.ModelForm):
136 | """
137 | 更新Host表单字段规则
138 | """
139 | Content = forms.CharField(label=u'Host配置内容', widget=forms.Textarea(attrs={'cols': '72', 'rows': '28'}))
140 |
141 | class Meta:
142 | forms.model = UpdateHost
143 |
--------------------------------------------------------------------------------
/PBS_Dynamic/web_api_forms.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/web_api_forms.pyc
--------------------------------------------------------------------------------
/PBS_Dynamic/web_api_paging.py:
--------------------------------------------------------------------------------
1 | # -*-coding:utf-8-*-
2 | # from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
3 |
4 |
5 | class Pagination(object):
6 |
7 | def __init__(self, total_count, current_page, page_url, per_page_item_num=15, max_page_num=12):
8 | """
9 | :param total_count: Total data
10 | :param current_page: current page
11 | :param per_page_item_num: Number of pages per page
12 | :param max_page_num: Display the maximum number of pages
13 | """
14 | # 数据总个数
15 | self.total_count = total_count
16 | # 当前页
17 | try:
18 | v = int(current_page)
19 | if v <= 0:
20 | v = 1
21 | self.current_page = v
22 | except Exception as e:
23 | self.current_page = 1
24 | # 每页显示的行数
25 | self.per_page_item_num = per_page_item_num
26 | # 最多显示页面
27 | self.max_page_num = max_page_num
28 | self.page_url = page_url
29 |
30 | def start(self):
31 | return (self.current_page-1) * self.per_page_item_num
32 |
33 | def end(self):
34 | return self.current_page * self.per_page_item_num
35 |
36 | @property
37 | def num_pages(self):
38 |
39 | a, b = divmod(self.total_count, self.per_page_item_num)
40 | if b == 0:
41 | return a
42 | return a+1
43 |
44 | def pager_num_range(self):
45 |
46 | if self.num_pages < self.max_page_num:
47 | return range(1, self.num_pages+1)
48 | # 总页数特别多 5
49 | part = int(self.max_page_num/2)
50 | if self.current_page <= part:
51 | return range(1, self.max_page_num+1)
52 | if (self.current_page + part) > self.num_pages:
53 | return range(self.num_pages-self.max_page_num+1, self.num_pages+1)
54 | return range(self.current_page-part, self.current_page+part+1)
55 |
56 | def page_str(self):
57 |
58 | page_list = []
59 |
60 | first = "首页 " % self.page_url
61 | page_list.append(first)
62 |
63 | if self.current_page == 1:
64 | prev = "上一页 "
65 | else:
66 | prev = "上一页 " % (self.current_page-1, self.page_url)
67 | page_list.append(prev)
68 | for i in self.pager_num_range():
69 | if i == self.current_page:
70 | temp = "%s " % (i, self.page_url, i)
71 | else:
72 | temp = "%s " % (i, self.page_url, i)
73 | page_list.append(temp)
74 |
75 | if self.current_page == self.num_pages:
76 | nex = "下一页 "
77 | else:
78 | nex = "下一页 " % (self.current_page + 1, self.page_url)
79 | page_list.append(nex)
80 |
81 | last = "尾页 " % (self.num_pages, self.page_url)
82 | page_list.append(last)
83 | page_msg = '第%s页/共%s页,合计%s条数据 ' % (self.current_page, self.num_pages, self.total_count)
84 | page_list.append(page_msg)
85 | return ''.join(page_list)
86 |
--------------------------------------------------------------------------------
/PBS_Dynamic/web_api_paging.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/PBS_Dynamic/web_api_paging.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Django admin WAPI
2 | The WAPI is an automation interface test platform
3 | developed based on the [Django admin](https://docs.djangoproject.com/en/2.0/ref/contrib/admin/) framework.
4 | Mainly composed of 7 modules:
5 |
6 | - API use case management system (add/delete/view/search use cases)
7 | - API suite management system (in a single system or in a single version for a set of packages)
8 | - API Task management system (asynchronous Task)
9 | - Environment system configuration (environment domain name Host or system domain name Host)
10 | - Log system (query record API execution results)
11 | - Feedback system (after troubleshoot the wrong reasons)
12 | - Statistical system (statistical API/system robustness, etc.)
13 |
14 | At the moment, Is a ` Django admin ` as the main framework implementations,
15 | Later will use ` Django + the Bootstrap + JS + RESTful ` technology to realize the comprehensive transformation,
16 | Now we has achieved five big modules, then we will further develop.
17 |
18 | # Features
19 | * Supports HTTP, HTTPS and SOAP protocol interfaces.
20 | * Support request parameterization and data transfer of associated interfaces.
21 | * Support ignition test, smoke, business process test, single interface test and generate test report.
22 | * Support sending mail and support sending WeChat push messages.
23 | * Support queue service to perform Task tasks.
24 | * Support for configuring multiple environments host (DEV \TEST\PROD environment), etc.
25 | * Support logging query
26 |
27 | # Dependencies
28 | Use Python 2.7 and
29 | Dependent libraries in [requirements.txt](https://github.com/wangxinglong007/WAPI/blob/master/requirements.txt)
30 | * Django==1.11
31 | * django-celery==3.2.1
32 | * django-kombu==0.9.4
33 | * mysqlclient==1.3.12
34 | * requests==2.18.4
35 | * redis==2.10.5
36 | * bs4==0.0.1
37 | * lxml==3.8.0
38 | * kombu==3.0.37
39 | * pyOpenSSL==17.0.0
40 | * pyv8==1.0
41 | * BeautifulSoup==3.2.1
42 | * beautifulsoup4==4.5.3
43 | * celery==3.1.25
44 |
45 |
46 | # Install and Configuration
47 | * Run pip install -r requirements.txt
48 | * And configuration [settings.py](https://github.com/wangxinglong007/WAPI/blob/master/ApiCaseSystem/settings.py)
49 |
50 |
51 | Windows installation `mysqlclient` can have a lot of problems, and you need
52 | install some application (For example)
53 |
54 | * [mysqlclient](https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient)
55 | * [Microsoft Visual C++ Compiler for Python 2.7](https://www.microsoft.com/en-us/download/details.aspx?id=44266)
56 | * [mysql-connector-c-6.0.2-winx64.msi](https://dev.mysql.com/downloads/connector/c/6.0.html)
57 |
58 | # Database
59 | * Create a database.
60 |
61 | CREATE DATABASE `wapi_db` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */
62 |
63 | * Import tables. Download this [test_django.sql](https://github.com/wangxinglong007/WAPI/blob/master/test_django.sql) file and import form you databases.
64 |
65 | * If there are some files in the migrations folder. First, you just need **`__init__.py`** and delete other files.
66 | Next Create file in **migrations** such:
67 |
68 | 1. python manage.py makemigrations
69 |
70 | 2. python manage.py migrate --fake
71 | (--fake this parameter is very important.)
72 |
73 | # Running
74 | You can deploy on [Apache](https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/modwsgi/) or run in you PC.
75 | For example in my PC:
76 |
77 | python manage.py runserver
78 | And if you need tasks function, must be running [celery](http://docs.celeryproject.org/en/3.1/django/index.html).
79 |
80 | python manage.py celery worker -l info
81 | python manage.py celery beat
82 |
83 | # Problems with deployment
84 | There may be problems with execute `python manage.py makemigrations`.
85 | 1. The mysql version does not support this. such as:
86 |
87 | ```django.db.utils.OperationalError: (2019, "Can't initialize character set utf8m64 (path: /usr/local/mysql/share/mysql/charsets/)")```
88 |
89 | Solution:
90 |
91 | **a.** Upgrade mysql to 5.5+
92 |
93 | **b.** Set DataBase Character set: **utf8mb4 -- UTF-8 Unicode** and Set collation **utf8mb4_unicode_ci**
94 | ```mysql
95 | CREATE DATABASE `wapi_db` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */
96 | ```
97 |
98 | 2. `djcelery.app.DjceleryConf ImportError: No module named DjceleryConf`
99 |
100 | Solution: Modify the code in `Python27\Lib\site-packages\djcelery\app.py`
101 | ```python
102 | # -*- coding: utf-8 -*-
103 | from __future__ import absolute_import, unicode_literals
104 |
105 | from celery import current_app
106 | from django.apps import AppConfig
107 |
108 | #: The Django-Celery app instance.
109 | app = current_app._get_current_object()
110 |
111 | class DjceleryConf(AppConfig):
112 | name = 'djcelery'
113 | verbose_name = u'Task'
114 | ```
115 |
116 | 3. `(1146, "Table 'django_apisys.PBS_Dynamic_testcase' doesn't exist")` Because, the mysql table name is case-insensitive in Windows and case sensitive in Linux.
117 |
118 | Solution: There are two ways to solve the problem.
119 |
120 | **a.** Add **db_table** an attribute to `model.py`. For example:
121 | ```python
122 | class TestCase(APITestCaseComment):
123 | .....
124 | User = models.CharField('user', max_length=32, null=True, blank=True)
125 | .....
126 |
127 | class Meta:
128 | ......
129 | db_table = 'PBS_Dynamic_testcase'
130 | ```
131 |
132 | **b.** Change the table name pbs_dynamic_testcase to PBS_Dynamic_testcase.
133 |
134 | # Plan
135 | * Use the [Django REST Framework](http://www.django-rest-framework.org/)
136 | * Add performance test functionality [locust](https://docs.locust.io/en/latest/)
137 | * Add statistical function (API, subsystem success rate, failure rate, etc.) [highcharts](https://www.hcharts.cn/demo/highcharts)
138 | * Use the [django-bootstrap](https://github.com/zostera/django-bootstrap4) refactoring page
139 | * Feedback system And automatically bring bug
140 |
141 | # Show
142 | 
143 | 
144 |
--------------------------------------------------------------------------------
/SOAP_API/__init__.py:
--------------------------------------------------------------------------------
1 | default_app_config = 'SOAP_API.apps.SoapApiConfig'
2 |
--------------------------------------------------------------------------------
/SOAP_API/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/__init__.pyc
--------------------------------------------------------------------------------
/SOAP_API/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.contrib import admin
5 |
6 | from .soap_api_forms import *
7 | import threading
8 | import datetime
9 | import re
10 |
11 | from WingOn import Main
12 | from PBS_Dynamic.DataCenter import *
13 | from WingOn.generateReport.HtmlReport import report
14 |
15 |
16 | def thread_func(some_result_list, common_data):
17 | """
18 | 多线程执行用例
19 | :param some_result_list: 根据用例id或者套件id查询出的用例列表
20 | :param common_data: 实例数据
21 | :return: 如果是套件的则返回 使用时间列表
22 | """
23 | suite_name = common_data.suite_name
24 | threads = []
25 | use_time_list = []
26 |
27 | for some_result in some_result_list:
28 | thd = threading.Thread(target=Main.run_main, args=(some_result, common_data))
29 | threads.append(thd)
30 |
31 | if suite_name:
32 | for ths in threads:
33 | begin_time = datetime.datetime.now()
34 | ths.start()
35 | ths.join()
36 | end_time = datetime.datetime.now()
37 | use_time = str(end_time - begin_time)
38 | use_time_list.append(use_time)
39 |
40 | return use_time_list
41 | else:
42 | for ths in threads:
43 | ths.start()
44 | ths.join()
45 |
46 |
47 | class SOAPTestCasesAdmin(admin.ModelAdmin):
48 |
49 | fields = ['Host', 'HostName', 'Description', 'SetupStep', 'Method', 'Headers',
50 | 'BodyValues', 'Expect', 'APIResult', 'Status', 'ExecutionTime', 'UseTime', 'User',
51 | 'Editor'] # 字段排序
52 | list_display = ('Description', 'HostName', 'id', 'setup_step', 'Method', 'status',
53 | 'ExecutionTime', )
54 | raw_id_fields = ("Host",)
55 | search_fields = ('id', 'Description')
56 |
57 | methods = 'test_case'
58 | suite_name = ''
59 | suite_system = ''
60 | case_id_list = []
61 | email_list = []
62 | pattern_list = []
63 |
64 | list_per_page = 50
65 | form = SOAPTestCasesForm
66 |
67 | def save_model(self, request, obj, form, change):
68 | obj.Editor = str(request.user)
69 | obj.save()
70 |
71 | def run_test_case(self, request, queryset):
72 | soap_data_center = SoapDataCenter()
73 | soap_data_center.environment = 'Test'
74 | common_run_case(request, soap_data_center)
75 |
76 | run_test_case.short_description = '执行Test 的 主测试用例'
77 |
78 | def run_uat_case(self, request, queryset):
79 | soap_data_center = SoapDataCenter()
80 | soap_data_center.environment = 'Uat'
81 | common_run_case(request, soap_data_center)
82 |
83 | run_uat_case.short_description = '执行Uat 的 主测试用例'
84 |
85 | def run_prod_case(self, request, queryset):
86 | soap_data_center = SoapDataCenter()
87 | soap_data_center.environment = 'Prod'
88 | common_run_case(request, soap_data_center)
89 |
90 | run_prod_case.short_description = '执行Prod 的 主测试用例'
91 |
92 | actions = [run_test_case, run_uat_case, run_prod_case]
93 |
94 |
95 | class SOAPSubTestCaseAdmin(admin.ModelAdmin):
96 | """
97 | 子用例表展示等
98 | copy_func 复制功能
99 | """
100 | fields = ['Host', 'HostName', 'SetupType', 'Description', 'Method', 'Headers',
101 | 'BodyValues', 'DataBox', 'APIResult', 'ExecutionTime', 'UseTime']
102 |
103 | list_display = ('Description', 'HostName', 'id', 'SetupType', 'Method', 'UseTime',
104 | 'ExecutionTime')
105 | search_fields = ('Description', 'id',)
106 | raw_id_fields = ("Host",)
107 |
108 | list_per_page = 50
109 | # list_filter = (HostListFilter,)
110 | form = SOAPSubTestCaseForm
111 |
112 |
113 | def common_run_case(request, soap_data_center):
114 | soap_data_center.methods = 'test_case'
115 | soap_data_center.user = str(request.user)
116 |
117 | soap_data_center.list_id = [i.replace('_selected_action=', '') for i in
118 | re.compile(r"(_[a-zA-Z]+_[a-zA-Z]+=\d+)").findall(request.body)]
119 | soap_data_center.start_time = datetime.datetime.now()
120 | some_result_list = []
121 | for i in soap_data_center.list_id:
122 | some_results = SOAPTestCases.objects.filter(id=i).values()
123 | some_result_list.append(some_results)
124 |
125 | thread_func(some_result_list, soap_data_center)
126 |
127 | end_time = datetime.datetime.now()
128 | soap_data_center.use_time = str(end_time - soap_data_center.start_time)
129 |
130 | report(soap_data_center)
131 |
132 | admin.site.register(SOAPTestCases, SOAPTestCasesAdmin)
133 | admin.site.register(SOAPSubTestCases, SOAPSubTestCaseAdmin)
134 |
135 |
--------------------------------------------------------------------------------
/SOAP_API/admin.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/admin.pyc
--------------------------------------------------------------------------------
/SOAP_API/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class SoapApiConfig(AppConfig):
8 | name = 'SOAP_API'
9 | verbose_name = 'SOAP接口测试用例管理系统'
--------------------------------------------------------------------------------
/SOAP_API/apps.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/apps.pyc
--------------------------------------------------------------------------------
/SOAP_API/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/migrations/__init__.py
--------------------------------------------------------------------------------
/SOAP_API/migrations/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/migrations/__init__.pyc
--------------------------------------------------------------------------------
/SOAP_API/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models
5 |
6 | import sys
7 | from django import forms
8 | from django.utils.html import format_html
9 |
10 | sys.path.append("..")
11 |
12 | from PBS_Dynamic.models import SystemHost, ReportCommon
13 |
14 |
15 | # Create your models here.
16 |
17 |
18 | class SOAPTestCaseComment(models.Model):
19 | """
20 | 公共基类模型
21 | 主用例 和 子用例继承
22 | """
23 | Host = models.ForeignKey(SystemHost, verbose_name='HOST环境路径', max_length=256)
24 | HostName = models.CharField('系统', max_length=256, blank=True)
25 | Description = models.CharField('测试用例描述', max_length=256)
26 | Method = models.CharField('方法', max_length=10)
27 | Headers = models.TextField('信息头')
28 | BodyValues = models.TextField('Body值', null=True, blank=True)
29 | APIResult = models.TextField('API结果', null=True, blank=True)
30 | ExecutionTime = models.DateTimeField('用例执行时间', null=True, blank=True)
31 | CreateTime = models.DateTimeField('用例创建时间', auto_now_add=True, null=True)
32 | UseTime = models.CharField('接口消耗时间(s)', max_length=32, null=True, blank=True)
33 |
34 | class Meta:
35 | abstract = True
36 |
37 |
38 | class SOAPTestCases(SOAPTestCaseComment):
39 | objects = None
40 | SetupStep = models.CharField('Setup步骤', max_length=256, blank=True)
41 | Expect = models.CharField('预期值', max_length=2048)
42 | Status = models.CharField('状态', max_length=10, null=True, blank=True)
43 | User = models.CharField('执行者', max_length=32, null=True, blank=True)
44 | Editor = models.CharField('创建/编辑者', max_length=32, null=True, blank=True)
45 |
46 | def __str__(self):
47 | return self.HostName
48 |
49 | def save(self, *args, **kwargs):
50 | get_host = SystemHost.objects.filter(id=self.Host_id).values_list('id', 'HostName')[0]
51 | if not self.HostName:
52 | self.HostName = get_host[1]
53 | else:
54 | new_get_host = SystemHost.objects.filter(id=self.Host_id).values_list('id', 'HostName')[0]
55 | if self.HostName != new_get_host[1]:
56 | self.HostName = new_get_host[1]
57 | else:
58 | self.HostName = get_host[1]
59 | super(SOAPTestCases, self).save(*args, **kwargs)
60 |
61 | def setup_step(self):
62 | return format_html(
63 | '{1}
',
64 | self.SetupStep,
65 | self.SetupStep,
66 | )
67 |
68 | def status(self):
69 | color = ''
70 | if self.Status == 'Success':
71 | color = '#6c6'
72 | elif self.Status == 'Fail':
73 | color = '#c60'
74 | elif self.Status == 'Error':
75 | color = '#c00'
76 |
77 | return format_html(
78 | '{1} ',
79 | color,
80 | self.Status,
81 | )
82 |
83 | setup_step.short_description = u'Setup步骤'
84 | status.short_description = u'状态'
85 |
86 | class Meta:
87 | verbose_name = 'SOAPTestCase'
88 | verbose_name_plural = '主测试用例'
89 | app_label = 'SOAP_API'
90 |
91 |
92 | class SOAPSubTestCases(SOAPTestCaseComment):
93 | objects = None
94 | SetupType = models.CharField('Setup类型', max_length=10)
95 | SetupIndex = models.CharField('关联主用例Setup步骤', max_length=32, blank=True)
96 | CaseID = models.CharField('关联主用例ID', max_length=32, blank=True)
97 | DataBox = models.CharField('数据值', max_length=1024, null=True, blank=True)
98 |
99 | def __str__(self):
100 | return self.HostName
101 |
102 | def save(self, *args, **kwargs):
103 | get_host = SystemHost.objects.filter(Uri=self.Host).values_list('HostName')[0]
104 |
105 | if not self.HostName:
106 | self.HostName = get_host[0]
107 | super(SOAPSubTestCases, self).save(*args, **kwargs)
108 | else:
109 |
110 | self.HostName = get_host[0]
111 | super(SOAPSubTestCases, self).save(*args, **kwargs)
112 |
113 | class Meta:
114 | verbose_name = 'SubTestCase'
115 | verbose_name_plural = u'子测试用例'
116 |
117 |
118 | class SoapReport(ReportCommon):
119 | """
120 | 继承ReportCommon 主用例报告模型
121 | """
122 | soapTestCase = models.ForeignKey(SOAPTestCases)
123 | Status = models.CharField('状态', max_length=10, null=True, blank=True)
124 |
125 | def __str__(self):
126 | return self.soapTestCase
127 |
128 |
129 | class SoapSubReport(ReportCommon):
130 | """
131 | 继承ReportCommon 主用例报告模型
132 | """
133 | soapSubCase = models.ForeignKey(SOAPSubTestCases)
134 |
135 | def __str__(self):
136 | return self.soapSubCase
137 |
--------------------------------------------------------------------------------
/SOAP_API/models.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/models.pyc
--------------------------------------------------------------------------------
/SOAP_API/soap_api_forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .models import *
3 | from django import forms
4 |
5 |
6 | class SOAPTestCasesForm(forms.ModelForm):
7 | """
8 | 定义主用例中的 字段规则,
9 | 默认是必填,required=False(选填)
10 | """
11 | # Host = forms.ChoiceField(label=u'HOST环境路径')
12 | HostName = forms.CharField(label=u'Host环境名', required=False, widget=forms.TextInput(
13 | attrs={'readonly': 'true'}))
14 | Description = forms.CharField(label=u'测试用例描述', widget=forms.Textarea(
15 | attrs={'cols': '85', 'rows': '1'}))
16 |
17 | Method = forms.ChoiceField(label=u'方法', choices=[('post', 'post'), ('get', 'get')])
18 |
19 | SetupStep = forms.CharField(label=u'Setup步骤', required=False, widget=forms.Textarea(
20 | attrs={'cols': '85', 'rows': '1'}))
21 |
22 | Expect = forms.CharField(label=u'预期值', widget=forms.Textarea(
23 | attrs={'cols': '85', 'rows': '8'}))
24 | APIResult = forms.CharField(label=u'API结果', required=False, widget=forms.Textarea(
25 | attrs={'readonly': 'true', 'cols': '85'}))
26 | Status = forms.CharField(label=u'状态', required=False, widget=forms.TextInput(
27 | attrs={'readonly': 'true', 'class': 'vTextField'}))
28 | UseTime = forms.CharField(label=u'接口消耗时间(s)', required=False, widget=forms.TextInput(
29 | attrs={'readonly': 'true', 'class': 'vTextField'}))
30 | ExecutionTime = forms.DateTimeField(label=u'用例执行时间', required=False, widget=forms.TextInput(
31 | attrs={'readonly': 'true', 'class': 'vTextField'}))
32 |
33 | class Meta:
34 | forms.model = SOAPTestCases
35 |
36 |
37 | class SOAPSubTestCaseForm(forms.ModelForm):
38 | """
39 | 定义子用例中的 字段规则,
40 | """
41 | Method = forms.ChoiceField(label=u'方法', choices=[('post', 'post'), ('get', 'get'), ('put', 'put')])
42 | DataBox = forms.CharField(label=u'数据值', widget=forms.Textarea(
43 | attrs={'cols': '85', 'rows': '8'}))
44 | APIResult = forms.CharField(label=u'API结果', required=False, widget=forms.Textarea(
45 | attrs={'readonly': 'true', 'cols': '85'}))
46 | UseTime = forms.CharField(label=u'接口消耗时间(s)', required=False, widget=forms.TextInput(
47 | attrs={'readonly': 'true', 'class': 'vTextField'}))
48 |
49 | HostName = forms.CharField(label=u'Host环境名', required=False, widget=forms.TextInput(
50 | attrs={'readonly': 'true'}))
51 |
52 | ExecutionTime = forms.DateTimeField(label=u'用例执行时间', required=False, widget=forms.TextInput(
53 | attrs={'readonly': 'true', 'class': 'vTextField'}))
54 |
55 | def __init__(self, *args, **kwargs):
56 | super(SOAPSubTestCaseForm, self).__init__(*args, **kwargs)
57 | self.fields['Host'].choices = ((host.Uri, host.Uri) for host in SystemHost.objects.all())
58 |
59 | class Meta:
60 | forms.model = SOAPSubTestCases
--------------------------------------------------------------------------------
/SOAP_API/soap_api_forms.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/SOAP_API/soap_api_forms.pyc
--------------------------------------------------------------------------------
/SOAP_API/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/SOAP_API/views.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.shortcuts import render
5 |
6 | # Create your views here.
7 |
--------------------------------------------------------------------------------
/WingOn/.idea/WingOn.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/WingOn/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/WingOn/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/WingOn/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WingOn/FightDataAndloadCase/ProcessData.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/FightDataAndloadCase/ProcessData.pyc
--------------------------------------------------------------------------------
/WingOn/FightDataAndloadCase/StructureData.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # coding:utf-8
3 |
4 |
5 | class StructureData:
6 | """
7 | 主用例结构体
8 | """
9 | def __init__(self):
10 | self.case_id = 0
11 | self.api_name = ''
12 | self.case_desc = ''
13 | self.set_up = ''
14 | self.url_parameter = ''
15 | self.method = ''
16 | self.headers = ''
17 | self.body_value = ''
18 | self.expect = ''
19 | self.api_result = ''
20 | self.status = []
21 | self.use_time = ''
22 | self.host = ''
23 | self.suite = ''
24 | self.execution_time = ''
25 | self.update_time = ''
26 | self.host_name = ''
27 |
28 |
29 | class SetUpStructureData:
30 | """
31 | 子用例结构体
32 | """
33 | def __init__(self):
34 | self.setup_index = ''
35 | self.case_id = ''
36 | self.api_name = ''
37 | self.description = ''
38 | self.url_parameter = ''
39 | self.method = ''
40 | self.headers = ''
41 | self.body_values = ''
42 | self.data_box = ''
43 | self.api_result = ''
44 | self.status = ''
45 | self.execution_time = ''
46 | self.use_time = ''
47 | self.id = ''
48 | self.host = ''
49 | self.host_name = ''
50 | self.set_up_type = ''
51 | self.expect = ''
52 |
53 |
54 | class SoapStructureData:
55 | """
56 | SOAP 主用例结构体
57 | """
58 | def __init__(self):
59 | self.case_id = 0
60 | self.api_name = ''
61 | self.case_desc = ''
62 | self.set_up = ''
63 | self.url_parameter = ''
64 | self.method = ''
65 | self.headers = ''
66 | self.body_value = ''
67 | self.expect = ''
68 | self.api_result = ''
69 | self.status = []
70 | self.use_time = ''
71 | self.host = ''
72 | self.suite = ''
73 | self.execution_time = ''
74 | self.update_time = ''
75 | self.host_name = ''
76 |
77 |
78 | class SoapSetUpStructureData:
79 | """
80 | 子用例结构体
81 | """
82 | def __init__(self):
83 | self.setup_index = ''
84 | self.case_id = ''
85 | self.description = ''
86 | self.method = ''
87 | self.headers = ''
88 | self.body_values = ''
89 | self.data_box = ''
90 | self.api_result = ''
91 | self.status = ''
92 | self.execution_time = ''
93 | self.use_time = ''
94 | self.id = ''
95 | self.host = ''
96 | self.host_name = ''
97 | self.set_up_type = ''
98 | self.expect = ''
99 |
--------------------------------------------------------------------------------
/WingOn/FightDataAndloadCase/StructureData.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/FightDataAndloadCase/StructureData.pyc
--------------------------------------------------------------------------------
/WingOn/FightDataAndloadCase/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/FightDataAndloadCase/__init__.py
--------------------------------------------------------------------------------
/WingOn/FightDataAndloadCase/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/FightDataAndloadCase/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/Main.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # coding:utf-8
3 |
4 | import sys
5 |
6 | from FightDataAndloadCase.ProcessData import ProcessData
7 | from WingOn.generateReport.HtmlReport import report, ignite_reports
8 |
9 | reload(sys)
10 | sys.setdefaultencoding('utf-8')
11 |
12 |
13 | def run_main(some_result, common_data):
14 | """
15 | :param some_result: 执行时勾选的数据
16 | :param common_data: 实例
17 | types: 类型 0 为 rest_api 1 为 soap_api
18 | :return:
19 | """
20 |
21 | # trans = ProcessData()
22 | if common_data.api_type == 0:
23 | ProcessData.process(some_result, common_data)
24 | elif common_data.api_type == 1:
25 | ProcessData.soap_process(some_result, common_data)
26 |
27 | # report(common_data)
28 |
29 |
--------------------------------------------------------------------------------
/WingOn/Main.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/Main.pyc
--------------------------------------------------------------------------------
/WingOn/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/__init__.py
--------------------------------------------------------------------------------
/WingOn/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/generateReport/HtmlReport.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/generateReport/HtmlReport.pyc
--------------------------------------------------------------------------------
/WingOn/generateReport/IgniteTemplateHtml.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 | # coding=utf-8
3 |
4 |
5 | class IgniteTemplateHtml:
6 |
7 | def __init__(self):
8 | pass
9 |
10 | @staticmethod
11 | def get_report_html():
12 | report_html = """
13 |
14 |
15 | 点火结果报告
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
41 |
42 |
43 |
44 |
45 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | API Automation Description
71 | User: {{ user }}
72 | StartTime: {{ start_time }}
73 | UseTime: {{ use_time }}
74 | Success: 与预期结果校验正确(ExpectResult)
75 | Fail: 与预期结果校验错误(ExpectResult)
76 | Error: 用例格式数据或输入错误
77 |
78 |
79 |
80 |
81 |
82 | Result Count
83 | Total: {{ counts.0 }}
84 | Status_200: {{ counts.1 }}
85 | Status_Other: {{ counts.2 }}
86 |
87 |
88 |
89 |
90 |
91 |
92 | ID
93 | SystemType
94 | ApiName
95 | Method
96 | Status
97 | ExecutionTime
98 | UseTime (S)
99 |
100 |
101 | {% for result in result_list %}
102 | {{ result.0 }}
103 | {{ result.1 }}
104 | {{ result.2 }}
105 | {{ result.3 }}
106 | {{ result.4 }}
107 | {{ result.5 }}
108 | {{ result.6 }}
109 |
110 | {% endfor %}
111 |
112 |
113 |
114 |
115 |
116 |
117 | """
118 | return report_html
119 |
--------------------------------------------------------------------------------
/WingOn/generateReport/IgniteTemplateHtml.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/generateReport/IgniteTemplateHtml.pyc
--------------------------------------------------------------------------------
/WingOn/generateReport/TemplateHtml.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/generateReport/TemplateHtml.pyc
--------------------------------------------------------------------------------
/WingOn/generateReport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/generateReport/__init__.py
--------------------------------------------------------------------------------
/WingOn/generateReport/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/generateReport/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/generateReport/clickA.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xinglongwang on 2017/3/22.
3 | */
4 |
5 |
6 |
7 | function display(d)
8 | {
9 |
10 | var ui = document.getElementById(d);
11 | if(ui.style.display=="block"){
12 | ui.style.display="none";
13 | }
14 | else{
15 | ui.style.display="block";
16 | }
17 |
18 | }
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/WingOn/methods/HttpEntity.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # coding:utf-8
3 |
4 | import json
5 | import requests
6 | import urllib
7 | import urllib2
8 | import ssl
9 | import time
10 |
11 | from PBS_Dynamic.DataCenter import *
12 |
13 | # 忽略https认证
14 | context = ssl._create_unverified_context()
15 | # requests.packages.urllib3.disable_warnings()
16 | ssl._create_default_https_context = ssl._create_unverified_context
17 |
18 |
19 | class HttpEntity:
20 |
21 | def __init__(self, host):
22 | self.host = host
23 |
24 | def post(self, api_name, headers, body, host_name, environment):
25 | """
26 | 构造post请求体
27 | :param host_name: host地址
28 | :param api_name: uri 如 /Search/FareRemarks
29 | :param headers: 请求的信息头
30 | :param body: 请求的body
31 | :return: 返回请求的结果
32 | """
33 |
34 | if 'https://' in api_name:
35 | url = api_name
36 | else:
37 | url = self.host + api_name
38 |
39 | data = json.dumps(body)
40 | # 进行旅客填写信息页面时,pbs系统会调用checkchange,api需要等待15s才返回结果
41 | if (host_name == 'PackageFHAPIDynamic' or host_name == 'PBSH5StaticL') and \
42 | '/Booking/SaveInfomation4FH' in api_name:
43 | if environment == 'Test':
44 | result = requests.post(url, data=data, headers=headers, verify=False)
45 | else:
46 | result = requests.post(url, data=data, headers=headers)
47 | time.sleep(30)
48 | if int(json.loads(result.text)['data']['NoResultYet4Resouce']) != 0:
49 | if environment == 'Test':
50 | result = requests.post(url, data=data, headers=headers, verify=False)
51 | else:
52 | result = requests.post(url, data=data, headers=headers)
53 |
54 | else:
55 | if environment == 'Test':
56 | result = requests.post(url, data=data, headers=headers, verify=False)
57 | else:
58 | result = requests.post(url, data=data, headers=headers)
59 | return result.text
60 |
61 | def urllib_post(self, api_name, headers, body):
62 | """
63 | 构造post请求体 (支付时 vco登录时用)
64 | :param api_name: uri 如 /Search/FareRemarks
65 | :param headers: 请求的信息头
66 | :param body: 请求的body
67 | :return: 返回请求的结果
68 | """
69 | if 'https://' in api_name:
70 | url = api_name
71 | else:
72 | url = self.host + api_name
73 |
74 | body_value = urllib.urlencode(body)
75 | request = urllib2.Request(url, body_value, headers)
76 |
77 | response = urllib2.urlopen(request)
78 | result = response.read()
79 |
80 | return result
81 |
82 | def get(self, api_name, value, environment):
83 | """
84 | 构造get 有参数的请求体
85 | :param api_name: uri 如 /Search/FareRemarks
86 | :param value: uri 后的参数 如 {"$top":1}
87 | :return: 返回请求的结果
88 | """
89 |
90 | url = self.host + api_name
91 | data = urllib.urlencode(value)
92 | last_url = url + '?' + data
93 | # last_url = http://xxx/xx/xxx/xx/Zones?$top=1
94 | request = urllib2.Request(last_url)
95 | # response = urllib2.urlopen(request)
96 | if environment == 'Test':
97 | response = urllib2.urlopen(request, context=context)
98 | else:
99 | response = urllib2.urlopen(request)
100 | result = response.read()
101 | return result
102 |
103 | def get_no_param(self, api_name, environment):
104 | """
105 | 构造get 无参数的请求体
106 | :param api_name: uri 如 /Search/FareRemarks
107 | :param environment: 环境 test https认证需要忽略
108 | :return: 返回请求的结果
109 | """
110 | url = self.host + api_name
111 | request = urllib2.Request(url)
112 | # response = urllib2.urlopen(request)
113 | if environment == 'Test':
114 | response = urllib2.urlopen(request, context=context)
115 | else:
116 | response = urllib2.urlopen(request)
117 | result = response.read()
118 | return result
119 |
120 | def put(self, api_name, headers, body, environment):
121 | """
122 | 构造put 请求体
123 | :param api_name: 接口uri
124 | :param headers: 信息头
125 | :param body: 请求内容
126 | :return: 返回的结果
127 | """
128 | if 'https://' in api_name:
129 | url = api_name
130 | else:
131 | url = self.host + api_name
132 |
133 | data = json.dumps(body)
134 | if environment == 'Test':
135 | result = requests.put(url, data=data, headers=headers, verify=False)
136 | else:
137 | result = requests.put(url, data=data, headers=headers)
138 |
139 | return result.text
140 |
141 | @staticmethod
142 | def soap_post(host, body, headers, environment):
143 | """
144 | 构造soap_post 请求体
145 | :param host:
146 | :param body:
147 | :param headers:
148 | :param environment:
149 | :return:
150 | """
151 | if environment == 'Test':
152 |
153 | result = requests.post(host, body, headers=headers, verify=False, stream=False)
154 | else:
155 | result = requests.post(host, body, headers=headers, stream=False)
156 |
157 | return result.content
158 |
159 |
160 | class IgniteHttpEntity(object):
161 | """
162 | 构造点火系统的请求
163 | requests (post、get、delete、put、options)
164 | urllib (urllib_methods)
165 | """
166 | def __init__(self):
167 | pass
168 |
169 | @staticmethod
170 | def post(host_url):
171 | result = requests.post(host_url, verify=False)
172 |
173 | return result.status_code
174 |
175 | @staticmethod
176 | def get(host_url):
177 | result = requests.get(host_url, verify=False)
178 |
179 | return result.status_code
180 |
181 | @staticmethod
182 | def delete(host_url):
183 | result = requests.delete(host_url, verify=False)
184 | return result.status_code
185 |
186 | @staticmethod
187 | def put(host_url):
188 | result = requests.delete(host_url, verify=False)
189 | return result.status_code
190 |
191 | @staticmethod
192 | def options(host_url):
193 | result = requests.options(host_url, verify=False)
194 | return result.status_code
195 |
196 | @staticmethod
197 | def urllib_methods(host_url):
198 | request = urllib2.Request(host_url)
199 | response = urllib2.urlopen(request, context=context)
200 | return response.getcode()
201 |
--------------------------------------------------------------------------------
/WingOn/methods/HttpEntity.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/methods/HttpEntity.pyc
--------------------------------------------------------------------------------
/WingOn/methods/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/methods/__init__.py
--------------------------------------------------------------------------------
/WingOn/methods/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/methods/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/reports/click.js:
--------------------------------------------------------------------------------
1 | function display(d) {
2 | var ui = document.getElementById(d);
3 | if(ui.style.display=="block"){
4 | ui.style.display="none";
5 | }
6 | else{
7 | ui.style.display="block";
8 | }
9 | }
10 | window.alert = alert;
11 | function alert(data) {
12 | var pup = document.createElement("div"),
13 | section = document.createElement("section")
14 | error_message = document.createElement("p"),
15 | btn = document.createElement("div"),
16 | error_title = document.createElement("div"),
17 | textNode = document.createTextNode(data ? data : ""),
18 | error_title_measage = document.createTextNode("");
19 | btnText = document.createTextNode("Close");
20 | // 控制样式
21 | css(pup, {
22 | "position" : "absolute",
23 | "left" : "20%",
24 | "right" : "20%",
25 | "top" : "10%",
26 | "bottom" : "30%",
27 | "margin" : "50px",
28 | "background-color" : "#FFFCEC",
29 | "text-align" : "left",
30 | //"width" : "auto",
31 | "overflow-x" : "auto",
32 | "overflow-y" : "auto"
33 | });
34 | css(error_message, {
35 | "font-size" : "15px",
36 | })
37 | css(btn, {
38 | "background" : "#999999",
39 | "text-align" : "right",
40 | "color" : "white",
41 | })
42 | // 内部结构套入
43 | btn.appendChild(btnText);
44 | pup.appendChild(btn);
45 |
46 | error_title.appendChild(error_title_measage);
47 | pup.appendChild(error_title);
48 |
49 | error_message.appendChild(textNode);
50 |
51 | pup.appendChild(section);
52 | section.appendChild(error_message);
53 |
54 |
55 | // 整体显示到页面内
56 | document.getElementsByTagName("body")[0].appendChild(pup);
57 | // 点击关闭按钮
58 | btn.onclick = function() {
59 | pup.parentNode.removeChild(pup);
60 | }
61 | }
62 | function css(targetObj, cssObj) {
63 | var str = targetObj.getAttribute("style") ? targetObj.getAttribute("style") : "";
64 | for(var i in cssObj) {
65 | str += i + ":" + cssObj[i] + ";";
66 | }
67 | targetObj.style.cssText = str;
68 | }
69 | //alert(ui.innerHTML);
70 |
71 | function display(d) {
72 | var ui = document.getElementById(d);
73 | alert(ui.innerHTML);
74 | //如果以弹框的形式,那这个就不显示
75 | /*if (ui.style.display == "block") {
76 | ui.style.display = "none";
77 | } else {
78 | ui.style.display = "block";
79 | }*/
80 | }
81 |
--------------------------------------------------------------------------------
/WingOn/requestBody/Check.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # coding:utf-8
3 |
4 | import sys
5 | import re
6 | import json
7 | import random
8 | import traceback
9 | from bs4 import BeautifulSoup
10 |
11 |
12 | reload(sys)
13 | sys.setdefaultencoding("utf-8")
14 |
15 | rule = re.compile(r"(\[.*?\])")
16 |
17 |
18 | class Check:
19 |
20 | def __init__(self, test_data):
21 | self.test_data = test_data
22 |
23 | @staticmethod
24 | def get_verify_data(routes, dicta, k):
25 | """
26 | 子用例数据值中的路径去获取dicta 中的 数据
27 | :param routes: 从子用例数据值中切出来的路径如head_errcode
28 | :param dicta: 子用例返回的结果
29 | :param k: 主用例中从verify中调用 返回结果
30 | :return:
31 | """
32 |
33 | dicta = json.loads(dicta)
34 |
35 | for route in routes:
36 | # print route
37 | # route = str(route)
38 |
39 | if '[' in route:
40 | split_list = route.split('[')
41 | if split_list[0]:
42 |
43 | get_key = split_list[0]
44 | # len_get_key = len(get_key)
45 | else:
46 | get_key = int(split_list[1].replace(']', ''))
47 |
48 | length = dicta[get_key]
49 | id_ = rule.findall(route)[0].replace('[', '').replace(']', '')
50 |
51 | # id_ = int(rule.findall(route)[0].replace('[', '').replace(']', ''))
52 | id_ = eval(json.loads(json.dumps(id_)))
53 | if not route.split('[')[0]:
54 | dicta = dicta[id_]
55 | else:
56 | dicta = dicta.get(route.split('[')[0])[id_]
57 |
58 | elif '-' in route:
59 | route = route.replace('-', '_')
60 | dicta = dicta.get(route)
61 | else:
62 | dicta = dicta.get(route)
63 |
64 | if ('have keys' or 'no keys') in k:
65 | return route
66 | else:
67 | return dicta
68 |
69 | def verify(self, result, dict_parameter):
70 | """
71 | 在主用例的期望字段的值切割,将值写入expect_result字典中,在调用verify_函数取值,最后检验值对不对或者字段存不存在
72 | :param result: 主用例的结果
73 | :param dict_parameter: 从子用例的数据值字段获取子用例结果添加到此字典中
74 | :return:
75 | """
76 | expect_result = {}
77 | # user = Check(self.test_data)
78 |
79 | for i in self.test_data.expect.split(','):
80 | if 'dict_parameter' in i:
81 | if str(eval(i.split(':')[0])) == str(i.split(':')[1]):
82 | self.test_data.status.append('Success')
83 | else:
84 | self.test_data.status.append('Fail')
85 | else:
86 | expect_result[tuple(i.split(':')[0].split('_'))] = i.split(':')[1]
87 |
88 | for j, k in expect_result.items():
89 | c = Check.get_verify_data(j, result, k)
90 | if 'have keys' in k:
91 |
92 | if c in result:
93 | self.test_data.status.append('Success')
94 | else:
95 | self.test_data.status.append('Fail')
96 | elif 'no keys' in k:
97 |
98 | if c not in result:
99 | self.test_data.status.append('Success')
100 | else:
101 | self.test_data.status.append('Fail')
102 | else:
103 |
104 | if str(c) == str(k): # assert
105 | self.test_data.status.append('Success')
106 | else:
107 | self.test_data.status.append('Fail')
108 |
109 | if 'Fail' in self.test_data.status:
110 | self.test_data.status = 'Fail'
111 | else:
112 | self.test_data.status = 'Success'
113 |
114 | @staticmethod
115 | def module_message(result, filter_string):
116 | filter_node = None
117 | try:
118 | soup = BeautifulSoup(result, "html.parser", from_encoding='utf-8')
119 | filter_list = filter_string.lower().split('_')
120 | result_list = soup.find_all('s:envelope')
121 |
122 | find_result = result_list[0]
123 |
124 | for filter_node in filter_list:
125 |
126 | result = find_result.find(filter_node)
127 |
128 | result_text = result.text
129 |
130 | except Exception as e:
131 | raise Exception(traceback.format_exc() + '请查看结果 或者 查看预期值{0}是否正确\n'.format(filter_node))
132 | return result_text
133 |
134 | def verify_soap(self, result):
135 | check_list = self.test_data.expect.split(',')
136 | for check_node in check_list:
137 | check_left = Check.module_message(result, check_node.split('=')[0])
138 | check_right = check_node.split('=')[1].replace('$', '')
139 |
140 | if str(check_left) == str(check_right):
141 | self.test_data.status.append('Success')
142 | else:
143 | self.test_data.status.append('Fail')
144 |
145 | if 'Fail' in self.test_data.status:
146 | self.test_data.status = 'Fail'
147 | else:
148 | self.test_data.status = 'Success'
149 |
150 |
151 | def randomLength(length):
152 | """
153 | :param length: list的值
154 | :return: 随机返回接口中list的长度
155 | """
156 | if len(length) == 0:
157 | raise Exception('此list为空,无法取到此列表的内容')
158 | else:
159 | return random.randint(0, len(length)-1)
160 |
161 |
162 |
--------------------------------------------------------------------------------
/WingOn/requestBody/Check.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/Check.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/InterfaceCase.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/InterfaceCase.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/RMQrecive.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # coding:utf-8
3 |
4 | import pika
5 | import redis
6 | from Rsa_encrypt.js import rsa_encryption_data
7 |
8 | credentials = pika.PlainCredentials('admin', 'admin')
9 | parameters = pika.ConnectionParameters('xxxx', 'port', 'xxxxTest', credentials)
10 | connection = pika.BlockingConnection(parameters)
11 | channel = connection.channel()
12 | channel.queue_declare(queue='AutoPayQueue')
13 | print '[*] Waiting for messages. To exit press CTRL+C'
14 | r = redis.Redis(host='xxx', port=port)
15 |
16 |
17 | def callback(ch, method, properties, body):
18 |
19 | list_body = eval(body).items()[0]
20 | # print list_body[0], rsa_encryption_data(list_body[1])
21 | r.set(list_body[0], rsa_encryption_data(list_body[1]), ex=1800)
22 | # channel.basic_consume(callback, queue = 'queue.abs.booking.searchflightlist' , no_ack = True )
23 | channel.basic_consume(callback, queue='AutoPayQueue', no_ack=True)
24 | channel.start_consuming()
25 |
26 |
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/RMQsend.py:
--------------------------------------------------------------------------------
1 | import pika
2 | import time
3 | import uuid
4 | import json
5 | import redis
6 | # channel.queue_declare(queue='queue.abs.booking.searchflightlist')
7 |
8 |
9 | def send_to_rmq(org_data):
10 | credentials = pika.PlainCredentials('admin', 'admin')
11 | parameters = pika.ConnectionParameters('host', 'port', 'xxxxTest', credentials)
12 | connection = pika.BlockingConnection(parameters)
13 | channel = connection.channel()
14 | uuid_ = uuid.uuid4().__str__()
15 | body = str({uuid_: org_data})
16 | channel.basic_publish(exchange='',
17 | # routing_key='queue.abs.booking.searchflightlist',
18 | routing_key='AutoPayQueue',
19 | body=body)
20 | # print " [x] Sent %s" %body
21 | connection.close()
22 | return uuid_
23 |
24 |
25 | def uuid_get_data(uuid):
26 | r = redis.Redis(host='host', port='port')
27 | while r.get(uuid) is None:
28 | time.sleep(0.5)
29 | return r.get(uuid)
30 |
31 |
32 | def rsa_data(need_data):
33 | return eval(uuid_get_data(send_to_rmq(need_data)))
34 |
35 |
36 |
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/RMQsend.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/RMQ/RMQsend.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/Rsa_encrypt/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'c.ma'
2 |
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/Rsa_encrypt/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/RMQ/Rsa_encrypt/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/Rsa_encrypt/js.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | __author__ = 'c.ma'
3 | import PyV8
4 | # from bs4 import BeautifulSoup
5 | import json
6 |
7 |
8 | def rsa_encryption_data(need_data):
9 | str_need_data = ''.join(json.dumps(need_data))
10 | with PyV8.JSContext() as ctxt:
11 | js_file = open(r'/var/www/html/ApiCaseSystem/WingOn/requestBody/RMQ/Rsa_encrypt/rsa.js', 'r')
12 | js_file_content = ''.join(js_file.readlines())
13 | js_file.close()
14 | ctxt.eval(js_file_content)
15 | rsa_data_ = ctxt.locals.a
16 | return list(rsa_data_(str_need_data))
17 |
18 |
19 | # def getCreditCardNumber(need_data):
20 | # str_need_data = str(need_data)
21 | # print str_need_data
22 | # # import PyV8
23 | # with PyV8.JSLocker() as ctxt:
24 | # ctxt = PyV8.JSContext()
25 | # ctxt.enter()
26 | # js_file = open(r'.\WingOn\requestBody\rsa.js', 'r')
27 | # js_file_content = ''.join(js_file.readlines())
28 | # # js_file.close()
29 | # ctxt.eval(js_file_content)
30 | # rsa_func = ctxt.locals.a
31 | # rsa_data_ = list(rsa_func(str_need_data))
32 | # ctxt.leave()
33 | # return rsa_data_
34 |
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/Rsa_encrypt/js.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/RMQ/Rsa_encrypt/js.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'c.ma'
2 |
--------------------------------------------------------------------------------
/WingOn/requestBody/RMQ/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/RMQ/__init__.pyc
--------------------------------------------------------------------------------
/WingOn/requestBody/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/__init__.py
--------------------------------------------------------------------------------
/WingOn/requestBody/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/WingOn/requestBody/__init__.pyc
--------------------------------------------------------------------------------
/celerybeat.pid:
--------------------------------------------------------------------------------
1 | 14378
2 |
--------------------------------------------------------------------------------
/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", "ApiCaseSystem.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError:
10 | # The above import may fail for some other reason. Ensure that the
11 | # issue is really that Django is missing to avoid masking other
12 | # exceptions on Python 2.
13 | try:
14 | import django
15 | except ImportError:
16 | raise ImportError(
17 | "Couldn't import Django. Are you sure it's installed and "
18 | "available on your PYTHONPATH environment variable? Did you "
19 | "forget to activate a virtual environment?"
20 | )
21 | raise
22 | execute_from_command_line(sys.argv)
23 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==1.11
2 | django-celery==3.2.1
3 | django-kombu==0.9.4
4 | mysqlclient==1.3.12
5 | requests==2.18.4
6 | redis==2.10.5
7 | bs4==0.0.1
8 | lxml==3.8.0
9 | kombu==3.0.37
10 | pyOpenSSL==17.0.0
11 | pyv8==1.0
12 | BeautifulSoup==3.2.1
13 | beautifulsoup4==4.5.3
14 | celery==3.1.25
--------------------------------------------------------------------------------
/static/WEB_API/css/common/paging.css:
--------------------------------------------------------------------------------
1 | #box{list-style:none;margin:0;padding:0;margin-left:2%;margin-top:1%;}
2 | #box li {
3 | color: #0084F3;
4 | text-align: center;
5 | width: 60px;
6 | height: 40px;
7 | border: 1px solid #ebebeb;
8 | line-height: 40px;
9 | box-sizing: border-box;
10 | cursor: pointer;
11 | float: left;
12 | }
13 | #box li a{
14 | display:block;
15 | width: 60px;
16 | height: 40px;
17 | line-height: 40px;
18 | }
19 | #box .active{background: #0084F3}
20 | #box .active a{color: white;}
21 | #box li a{text-decoration:none;}
22 | #box span{margin-left: 20px;height: 40px;line-height: 40px;}
--------------------------------------------------------------------------------
/static/WEB_API/css/common/paging.less:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | list-style: none;
5 | }
6 |
7 | .fl {
8 | float: left;
9 | }
10 |
11 | .box {
12 | height: 40px;
13 | line-height: 40px;
14 | position: absolute;
15 | left: 50%;
16 | top: 50%;
17 | transform: translate(-50%, -50%);
18 | text-align: center; // 按钮
19 | button {
20 | padding: 0 10px;
21 | margin: 0 10px;
22 | height: 40px;
23 | .fl;
24 | cursor: pointer;
25 | border: 1px solid #ebebeb;
26 | background-color: #ffffff;
27 | } // 首页、尾页按钮
28 | .first-page,
29 | .last-page {
30 | margin: 0;
31 | } // 页码块
32 | .pageWrap {
33 | height: 40px;
34 | .fl;
35 | overflow: hidden;
36 | ul {
37 | width: 100000px;
38 | height: 40px;
39 | .fl;
40 | li {
41 | width: 60px;
42 | height: 40px;
43 | border: 1px solid #ebebeb;
44 | line-height: 40px;
45 | box-sizing: border-box;
46 | cursor: pointer;
47 | .fl;
48 | } // 选中页码
49 | .sel-page {
50 | background-color: yellow; //选中时的颜色
51 | }
52 | }
53 | } // 跳转页
54 | .jump-text {
55 | width: 60px;
56 | height: 40px;
57 | box-sizing: border-box;
58 | text-align: center;
59 | margin: 0 5px;
60 | .fl;
61 | } // 跳转按钮
62 | .jump-button {
63 | margin:0;
64 | .fl;
65 | } // 总页数,总条目数
66 | .total-pages,
67 | .total-count {
68 | margin-left: 10px;
69 | .fl;
70 | font-size: 14px;
71 | }
72 | }
--------------------------------------------------------------------------------
/static/WEB_API/css/log/check_log.css:
--------------------------------------------------------------------------------
1 | #loading{width:100%;height:100%;background:#000;opacity:0;
2 | position:absolute;top:0px;color:white;z-index:50;
3 | font-size:36px;font-family:'微软雅黑';text-align:center;padding-top:25%;
4 | -webkit-transition:all 2s;display:none;}
5 | #mainview{
6 | width: 90%;margin-top: 1%;margin-left:5%;
7 | -moz-box-shadow: 0 0 5px;/*firefox*/
8 | -webkit-box-shadow: 0 0 5px;/*webkit*/
9 | box-shadow: 0 0 5px;/*opera或ie9*/
10 | -moz-border-radius:5px;
11 | -webkit-border-radius:5px;
12 | border-radius: 5px;
13 | padding: 5px;}
14 | #tarTop{
15 | text-align: center; background: #0084F3;
16 | height: 3%;
17 | font-family: '微软雅黑';font-size: 24px;font-weight: bold;line-height: 40px;color: white;
18 | -moz-box-shadow: 0 0 3px;
19 | -webkit-box-shadow: 0 0 3px;
20 | box-shadow: 0 0 3px;
21 | -moz-border-radius: 5px;
22 | -webkit-border-radius: 5px;
23 | border-radius: 5px; }
24 | /*40px=3%*/
25 | #oform{ margin-top: 1.5%; }
26 | #input_div{margin-left:1%;width: 98%;}
27 | #sel{width: 10%;}
28 | #click_time{width: 12%;}
29 | #end_time{width: 12%;}
30 | /*restapi 系统选择*/
31 | #systemcode{width: 15%;font-size: 18px;}
32 | /*soapapi 系统选择*/
33 | #soap_system_code{width: 15.7%;font-size: 16px;}
34 |
35 | #enviorment{width: 10%;}
36 | #case_id{width: 8%;height: 37px;}
37 | #sub_case_id{width: 8%;}
38 | #submit_btn{width:5%;background:#0084F3;color:white;margin-left:5%}
39 | #submit_btn:hover{opacity:0.6;}
40 |
41 |
42 |
43 | #search_thread{margin: 0 auto;margin-top: 2%;height:40px;background: #11A0FF; color: white; font-weight: bold; border-radius: 5px;}
44 | #search_thread table{width:97%; height:100%;text-align: left;margin-left: 2%;border-collapse: separate;}
45 | /*#search_thread table tr td{background: red}
46 | .div_title table tr td{background: black;}*/
47 | /*开始执行时间*/
48 | #search_thread .ClickExecutionTime2{width:15.5%;}
49 | /*接口名称*/
50 | #search_thread .testCase__ApiName2{width: 33%;}
51 | /*描述*/
52 | #search_thread .testCase__Description2{width: 21.6%;}
53 | /*ID*/
54 | #search_thread .testCase_id2{width: 5%;}
55 | /*执行步骤*/
56 | #search_thread .testCase__SetupStep2{width: 11%;}
57 | /*环境*/
58 | #search_thread .Environment2{width: 5%;}
59 | /*结果*/
60 | #search_thread .Status2{width: 9%;}
61 | /*子用例使用样式 ID 步骤类型*/
62 | #search_thread .SubCaseID_id2{width: 8%;}
63 | #search_thread .SubCaseID__SetupType2{width: 8%;}
64 |
65 | /* soap 用例样式 testCase_id2*/
66 | #search_thread .soapTestCase_id2{width: 8%;}
67 | #search_thread .soapTestCase__SetupStep2{width: 8%;}
68 | #search_thread .soapSubCase_id2{width: 5%;}
69 |
70 |
71 | /*log内容样式*/
72 | #accordion{--webkit-box-shadow: 0 0 5px; margin-top: 0.5%;}
73 | #accordion div:nth-child(even){display:none;padding:25px;text-align:left;background:#F7F7F7;word-break: break-all;word-wrap:break-word;};
74 | #accordion div:nth-child(odd){height:40px;};
75 | .div_title{border-radius:10px;box-shadow: 0 0 5px #CCCCCC;}
76 | .div_title table{height:40px;border-bottom:1px solid #DDD;width: 97%;margin-left:2%;table-layout: fixed; text-align: left;border-collapse: separate;word-break: break-all; word-wrap: break-word;}
77 | .div_title table tr td{overflow: hidden;text-overflow:ellipsis;white-space: nowrap;}
78 | /*开始执行时间*/
79 | .div_title .ClickExecutionTime{width: 15.5%;}
80 | /*接口名称*/
81 | .div_title .testCase__ApiName,.SubCaseID__ApiName{width: 33%;}
82 | /*描述*/
83 | .div_title .testCase__Description,.SubCaseID__Description{width: 21.6%;}
84 | /*ID*/
85 | .div_title .testCase_id,.SubCaseID_id{width: 5%;}
86 | .div_title .SubCaseID_id{width: 8%;}
87 | /*执行步骤||步骤类型*/
88 | .div_title .testCase__SetupStep,.SubCaseID__SetupType{width: 11%;}
89 | .div_title .SubCaseID__SetupType{width: 8%;}
90 | /*环境*/
91 | .div_title .Environment{width: 5%;}
92 | /*结果状态*/
93 | .div_title .Status{ width: 9%; color:#6c6; font-weight:bold;}
94 |
95 | /* soap 主用例样式 testCase_id2*/
96 | .div_title .soapSubCase_id{width: 5%;}
97 | .div_title .soapTestCase_id{width: 8%;}
98 |
99 | .div_title .soapTestCase__Description,.soapSubCase__Description{width: 21.6%;}
100 | .div_title .soapTestCase__SetupStep,.soapSubCase__SetupType{width: 8%;}
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/static/WEB_API/js/common/paging.min.js:
--------------------------------------------------------------------------------
1 | (function(d, c, a) {
2 | function b(f, e) {
3 | this.el = f;
4 | this.options = { pageNo: e.initPageNo || 1, totalPages: e.totalPages || 1, totalCount: e.totalCount || "", slideSpeed: e.slideSpeed || 0, jump: e.jump || false, callback: e.callback || function() {} };
5 | this.init()
6 | }
7 | b.prototype = {
8 | constructor: b,
9 | init: function() {
10 | this.createDom();
11 | this.bindEvents()
12 | },
13 | createDom: function() {
14 | var k = this,
15 | m = "",
16 | e = "",
17 | j = "",
18 | g = 60,
19 | h = k.options.totalPages,
20 | l = 0;
21 | h > 5 ? l = 5 * g : l = h * g;
22 | for (var f = 1; f <= k.options.totalPages; f++) { f != 1 ? m += "" + f + " " : m += '' + f + " " }
23 | k.options.jump ? e = '跳转 ' : e = "";
24 | j = '首页 ' + '上一页 ' + '" + '下一页 ' + '尾页 ' + e + '共 ' + k.options.totalPages + " 页
" + '' + k.options.totalCount + "
";
25 | k.el.html(j)
26 | },
27 | bindEvents: function() {
28 | var k = this,
29 | f = d("#pageSelect"),
30 | r = f.children(),
31 | n = r[0].offsetWidth,
32 | l = k.options.totalPages,
33 | g = k.options.pageNo,
34 | e = 0,
35 | o = d("#prePage"),
36 | m = d("#nextPage"),
37 | i = d("#firstPage"),
38 | j = d("#lastPage"),
39 | q = d("#jumpBtn"),
40 | h = d("#jumpText");
41 | o.on("click", function() {
42 | g--;
43 | if (g < 1) { g = 1 }
44 | p(g)
45 | });
46 | m.on("click", function() {
47 | g++;
48 | if (g > r.length) { g = r.length }
49 | p(g)
50 | });
51 | i.on("click", function() {
52 | g = 1;
53 | p(g)
54 | });
55 | j.on("click", function() {
56 | g = l;
57 | p(g)
58 | });
59 | q.on("click", function() {
60 | var s = parseInt(h.val().replace(/\D/g, ""));
61 | if (s && s >= 1 && s <= l) {
62 | g = s;
63 | p(g);
64 | h.val(s)
65 | }
66 | });
67 | r.on("click", function() {
68 | g = d(this).index() + 1;
69 | p(g)
70 | });
71 |
72 | function p(s) {
73 | r.removeClass("sel-page").eq(s - 1).addClass("sel-page");
74 | if (l <= 5) { k.options.callback(s); return false }
75 | if (s >= 3 && s <= l - 2) { e = (s - 3) * n }
76 | if (s == 2 || s == 1) { e = 0 }
77 | if (s > l - 2) { e = (l - 5) * n }
78 | f.css("transform", "translateX(" + (-e) + "px)");
79 | s == 1 ? i.attr("disabled", true) : i.attr("disabled", false);
80 | s == 1 ? o.attr("disabled", true) : o.attr("disabled", false);
81 | s == l ? j.attr("disabled", true) : j.attr("disabled", false);
82 | s == l ? m.attr("disabled", true) : m.attr("disabled", false);
83 | k.options.callback(s)
84 | }
85 | p(k.options.pageNo)
86 | }
87 | };
88 | d.fn.paging = function(e) { return new b(d(this), e) }
89 | })(jQuery, window, document);
--------------------------------------------------------------------------------
/static/WEB_API/js/log/check_log.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | $('#sub_case_id').attr("disabled","disabled");
3 | $('#soap_system_code').css('display','none');
4 | });
5 | //主用例/子用例切换响应事件
6 | function chg(){
7 | if(document.getElementById("sel").value=="0"){
8 |
9 | $('#sub_case_id').attr("disabled","disabled");
10 | $('#sub_case_id').val('');
11 | }
12 | else{
13 | $('#sub_case_id').removeAttr("disabled");
14 | $('#sub_case_id').val('');
15 |
16 | }
17 | };
18 |
19 | //SoapAPI/RestAPI切换响应事件
20 | function changeType(){
21 | if(document.getElementById("api_type").value=="SoapAPI"){
22 | document.getElementById("soap_system_code").style.display='';
23 | document.getElementById("system_code").style.display='none';
24 | }else{
25 | document.getElementById("soap_system_code").style.display='none';
26 | document.getElementById("system_code").style.display='';
27 | }
28 | }
29 | $(function() {
30 | $( "#click_time" ).datetimepicker({
31 | format:'Y-m-d H:i:s',
32 | step:10
33 | });
34 | $( "#end_time" ).datetimepicker({
35 | format:'Y-m-d H:i:s',
36 | step:10
37 | });
38 | });
39 |
40 |
41 | //日志详情展开 方法
42 | function logSlideToggle(){
43 | $(".div_title").click(function(){
44 | $(this).next().slideToggle();
45 | });
46 | }
47 | //状态颜色 方法
48 | function statusColor(){
49 | var table_content=$('.table_content');
50 | var i=0;
51 | for( var i = 0; i < table_content.length; i++ ) {
52 |
53 | var result_td=table_content.eq(i).children("td:last-child");
54 | if(result_td.html()=='Fail'){
55 | result_td.css('color','#c60');
56 | }
57 | else if(result_td.html()=='Error'){
58 | result_td.css('color','#c00');
59 | }
60 | else if(result_td.html()=='Success'){
61 | result_td.css('color','#6c6');
62 | }else{
63 | ;
64 | }
65 | }
66 | }
67 | //分页链接 点击响应 方法
68 | function linkClick(){
69 | $('a').click(function(){
70 | var oLink=$(this).attr('href');
71 | //alert(oLink);
72 | $.ajax({
73 | url: oLink,
74 | success: function(result, statues, xml){
75 | //alert('进入分页回调');
76 | //alert(result);
77 | $("#response_result").html(result);
78 | logSlideToggle();
79 | statusColor();
80 | linkClick();
81 | },
82 | error: function(){
83 | alert("false");
84 | },
85 | dataType: "html"
86 | });
87 | return false;
88 | });
89 | }
90 | //页面加载完成 方法 查询提交请求
91 | $(document).ready(function(){
92 | $.ajaxSetup({
93 | data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
94 | });
95 | //查询提交 get请求
96 | $('#submit_btn').click(function(){
97 | //alert('进入submit');
98 | var csrfmiddlewaretoken='{{ csrf_token }}';
99 | var api_type = $("#api_type").val();
100 | var case_type = $("#sel").val();
101 | var click_time = $("#click_time").val();
102 | var end_time = $("#end_time").val();
103 | var system_code = $("#system_code").val();
104 | var soap_system_code = $("#soap_system_code").val();
105 | var environment = $("#environment").val();
106 | var case_id = $("#case_id").val();
107 | var sub_case_id = $("#sub_case_id").val();
108 | //正整数正则表达式 1-9开头
109 | var reg=/^[1-9]\d*$|^0$/;
110 | if(click_time==''||end_time==''){
111 | alert('开始时间和结束时间不能为空');
112 | $("#click_time").focus();
113 | return false;
114 | }else if(click_time>end_time){
115 | alert('开始时间不能早于结束时间');
116 | $("#click_time").focus();
117 | return false;
118 | }else if(case_type=='1'&&(case_id&&!(sub_case_id)||(sub_case_id&&(!case_id)))){
119 | if(case_id&&!(sub_case_id)){alert('有主用例ID时 必须输入子用例ID');$("#sub_case_id").focus();}
120 | else{alert('有子用例ID时 必须输入主用例ID');$("#case_id").focus();}
121 | return false;
122 | }else if(case_type=='1'&&!(!case_id&&!sub_case_id)&&(reg.test(case_id)==false||reg.test(sub_case_id)==false)){
123 | alert('请输入正确的ID');
124 | return false;
125 | }else if(case_type=='0'&&case_id&®.test(case_id)==false){
126 | alert('请输入正确的主用例ID');
127 | $("#case_id").focus();
128 | return false;
129 | }
130 | else{
131 | document.getElementById("loading").style.display='block';
132 | document.getElementById("loading").style.opacity='0.6';
133 | $.ajax({
134 | type:"GET",
135 | data: {api_type:api_type,case_type:case_type,click_time:click_time,
136 | end_time:end_time,system_code:system_code,soap_system_code:soap_system_code,
137 | environment:environment,case_id:case_id,sub_case_id:sub_case_id},
138 | url: "/log/",
139 | cache: false,
140 | dataType: "html",
141 | /*ajax成功时回调方法*/
142 | success: function(result, statues, xml){
143 | //关闭 loading
144 | document.getElementById("loading").style.display='none';
145 | //局部刷新数据
146 | $("#response_result").html(result);
147 | //加载分页提交事件
148 | linkClick();
149 | //加载数据下拉事件
150 | logSlideToggle();
151 | //加载状态颜色事件
152 | statusColor();
153 | },
154 | error: function(){
155 | alert("false");
156 | }
157 | });
158 | return false;
159 | }
160 | });
161 | });
162 |
--------------------------------------------------------------------------------
/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: none;
16 | }
17 |
18 | .change-list .filtered {
19 | min-height: 400px;
20 | }
21 |
22 | .change-list .filtered .results, .change-list .filtered .paginator,
23 | .filtered #toolbar, .filtered div.xfull {
24 | margin-right: 280px;
25 | width: auto;
26 | }
27 |
28 | .change-list .filtered table tbody th {
29 | padding-right: 1em;
30 | }
31 |
32 | #changelist-form .results {
33 | overflow-x: auto;
34 | }
35 |
36 | #changelist .toplinks {
37 | border-bottom: 1px solid #ddd;
38 | }
39 |
40 | #changelist .paginator {
41 | color: #666;
42 | border-bottom: 1px solid #eee;
43 | background: #fff;
44 | overflow: hidden;
45 | }
46 |
47 | /* CHANGELIST TABLES */
48 |
49 | #changelist table thead th {
50 | padding: 0;
51 | white-space: nowrap;
52 | vertical-align: middle;
53 | }
54 |
55 | #changelist table thead th.action-checkbox-column {
56 | width: 1.5em;
57 | text-align: center;
58 | }
59 |
60 | #changelist table tbody td.action-checkbox {
61 | text-align: center;
62 | }
63 |
64 | #changelist table tfoot {
65 | color: #666;
66 | }
67 |
68 | /* TOOLBAR */
69 |
70 | #changelist #toolbar {
71 | padding: 8px 10px;
72 | margin-bottom: 15px;
73 | border-top: 1px solid #eee;
74 | border-bottom: 1px solid #eee;
75 | background: #f8f8f8;
76 | color: #666;
77 | }
78 |
79 | #changelist #toolbar form input {
80 | border-radius: 4px;
81 | font-size: 14px;
82 | padding: 5px;
83 | color: #333;
84 | }
85 |
86 | #changelist #toolbar form #searchbar {
87 | height: 19px;
88 | border: 1px solid #ccc;
89 | padding: 2px 5px;
90 | margin: 0;
91 | vertical-align: top;
92 | font-size: 13px;
93 | }
94 |
95 | #changelist #toolbar form #searchbar:focus {
96 | border-color: #999;
97 | }
98 |
99 | #changelist #toolbar form input[type="submit"] {
100 | border: 1px solid #ccc;
101 | padding: 2px 10px;
102 | margin: 0;
103 | vertical-align: middle;
104 | background: #fff;
105 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
106 | cursor: pointer;
107 | color: #333;
108 | }
109 |
110 | #changelist #toolbar form input[type="submit"]:focus,
111 | #changelist #toolbar form input[type="submit"]:hover {
112 | border-color: #999;
113 | }
114 |
115 | #changelist #changelist-search img {
116 | vertical-align: middle;
117 | margin-right: 4px;
118 | }
119 |
120 | /* FILTER COLUMN */
121 |
122 | #changelist-filter {
123 | position: absolute;
124 | top: 0;
125 | right: 0;
126 | z-index: 1000;
127 | width: 240px;
128 | background: #f8f8f8;
129 | border-left: none;
130 | margin: 0;
131 | }
132 |
133 | #changelist-filter h2 {
134 | font-size: 14px;
135 | text-transform: uppercase;
136 | letter-spacing: 0.5px;
137 | padding: 5px 15px;
138 | margin-bottom: 12px;
139 | border-bottom: none;
140 | }
141 |
142 | #changelist-filter h3 {
143 | font-weight: 400;
144 | font-size: 14px;
145 | padding: 0 15px;
146 | margin-bottom: 10px;
147 | }
148 |
149 | #changelist-filter ul {
150 | margin: 5px 0;
151 | padding: 0 15px 15px;
152 | border-bottom: 1px solid #eaeaea;
153 | }
154 |
155 | #changelist-filter ul:last-child {
156 | border-bottom: none;
157 | padding-bottom: none;
158 | }
159 |
160 | #changelist-filter li {
161 | list-style-type: none;
162 | margin-left: 0;
163 | padding-left: 0;
164 | }
165 |
166 | #changelist-filter a {
167 | display: block;
168 | color: #999;
169 | text-overflow: ellipsis;
170 | overflow-x: hidden;
171 | }
172 |
173 | #changelist-filter li.selected {
174 | border-left: 5px solid #eaeaea;
175 | padding-left: 10px;
176 | margin-left: -15px;
177 | }
178 |
179 | #changelist-filter li.selected a {
180 | color: #5b80b2;
181 | }
182 |
183 | #changelist-filter a:focus, #changelist-filter a:hover,
184 | #changelist-filter li.selected a:focus,
185 | #changelist-filter li.selected a:hover {
186 | color: #036;
187 | }
188 |
189 | /* DATE DRILLDOWN */
190 |
191 | .change-list ul.toplinks {
192 | display: block;
193 | float: left;
194 | padding: 0;
195 | margin: 0;
196 | width: 100%;
197 | }
198 |
199 | .change-list ul.toplinks li {
200 | padding: 3px 6px;
201 | font-weight: bold;
202 | list-style-type: none;
203 | display: inline-block;
204 | }
205 |
206 | .change-list ul.toplinks .date-back a {
207 | color: #999;
208 | }
209 |
210 | .change-list ul.toplinks .date-back a:focus,
211 | .change-list ul.toplinks .date-back a:hover {
212 | color: #036;
213 | }
214 |
215 | /* PAGINATOR */
216 |
217 | .paginator {
218 | font-size: 13px;
219 | padding-top: 10px;
220 | padding-bottom: 10px;
221 | line-height: 22px;
222 | margin: 0;
223 | border-top: 1px solid #ddd;
224 | }
225 |
226 | .paginator a:link, .paginator a:visited {
227 | padding: 2px 6px;
228 | background: #79aec8;
229 | text-decoration: none;
230 | color: #fff;
231 | }
232 |
233 | .paginator a.showall {
234 | padding: 0;
235 | border: none;
236 | background: none;
237 | color: #5b80b2;
238 | }
239 |
240 | .paginator a.showall:focus, .paginator a.showall:hover {
241 | background: none;
242 | color: #036;
243 | }
244 |
245 | .paginator .end {
246 | margin-right: 6px;
247 | }
248 |
249 | .paginator .this-page {
250 | padding: 2px 6px;
251 | font-weight: bold;
252 | font-size: 13px;
253 | vertical-align: top;
254 | }
255 |
256 | .paginator a:focus, .paginator a:hover {
257 | color: white;
258 | background: #036;
259 | }
260 |
261 | /* ACTIONS */
262 |
263 | .filtered .actions {
264 | margin-right: 280px;
265 | border-right: none;
266 | }
267 |
268 | #changelist table input {
269 | margin: 0;
270 | vertical-align: baseline;
271 | }
272 |
273 | #changelist table tbody tr.selected {
274 | background-color: #FFFFCC;
275 | }
276 |
277 | #changelist .actions {
278 | padding: 10px;
279 | background: #fff;
280 | border-top: none;
281 | border-bottom: none;
282 | line-height: 24px;
283 | color: #999;
284 | }
285 |
286 | #changelist .actions.selected {
287 | background: #fffccf;
288 | border-top: 1px solid #fffee8;
289 | border-bottom: 1px solid #edecd6;
290 | }
291 |
292 | #changelist .actions span.all,
293 | #changelist .actions span.action-counter,
294 | #changelist .actions span.clear,
295 | #changelist .actions span.question {
296 | font-size: 13px;
297 | margin: 0 0.5em;
298 | display: none;
299 | }
300 |
301 | #changelist .actions:last-child {
302 | border-bottom: none;
303 | }
304 |
305 | #changelist .actions select {
306 | vertical-align: top;
307 | height: 24px;
308 | background: none;
309 | color: #000;
310 | border: 1px solid #ccc;
311 | border-radius: 4px;
312 | font-size: 14px;
313 | padding: 0 0 0 4px;
314 | margin: 0;
315 | margin-left: 10px;
316 | }
317 |
318 | #changelist .actions select:focus {
319 | border-color: #999;
320 | }
321 |
322 | #changelist .actions label {
323 | display: inline-block;
324 | vertical-align: middle;
325 | font-size: 13px;
326 | }
327 |
328 | #changelist .actions .button {
329 | font-size: 13px;
330 | border: 1px solid #ccc;
331 | border-radius: 4px;
332 | background: #fff;
333 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
334 | cursor: pointer;
335 | height: 24px;
336 | line-height: 1;
337 | padding: 4px 8px;
338 | margin: 0;
339 | color: #333;
340 | }
341 |
342 | #changelist .actions .button:focus, #changelist .actions .button:hover {
343 | border-color: #999;
344 | }
345 |
--------------------------------------------------------------------------------
/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 | overflow: hidden;
25 | text-overflow: ellipsis;
26 | -o-text-overflow: ellipsis;
27 | }
28 |
--------------------------------------------------------------------------------
/static/admin/css/fonts.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Roboto';
3 | src: url('../fonts/Roboto-Bold-webfont.woff');
4 | font-weight: 700;
5 | font-style: normal;
6 | }
7 |
8 | @font-face {
9 | font-family: 'Roboto';
10 | src: url('../fonts/Roboto-Regular-webfont.woff');
11 | font-weight: 400;
12 | font-style: normal;
13 | }
14 |
15 | @font-face {
16 | font-family: 'Roboto';
17 | src: url('../fonts/Roboto-Light-webfont.woff');
18 | font-weight: 300;
19 | font-style: normal;
20 | }
21 |
--------------------------------------------------------------------------------
/static/admin/css/login.css:
--------------------------------------------------------------------------------
1 | /* LOGIN FORM */
2 |
3 | body.login {
4 | background: #f8f8f8;
5 | }
6 |
7 | .login #header {
8 | height: auto;
9 | padding: 5px 16px;
10 | }
11 |
12 | .login #header h1 {
13 | font-size: 18px;
14 | }
15 |
16 | .login #header h1 a {
17 | color: #fff;
18 | }
19 |
20 | .login #content {
21 | padding: 20px 20px 0;
22 | }
23 |
24 | .login #container {
25 | background: #fff;
26 | border: 1px solid #eaeaea;
27 | border-radius: 4px;
28 | overflow: hidden;
29 | width: 28em;
30 | min-width: 300px;
31 | margin: 100px auto;
32 | }
33 |
34 | .login #content-main {
35 | width: 100%;
36 | }
37 |
38 | .login .form-row {
39 | padding: 4px 0;
40 | float: left;
41 | width: 100%;
42 | border-bottom: none;
43 | }
44 |
45 | .login .form-row label {
46 | padding-right: 0.5em;
47 | line-height: 2em;
48 | font-size: 1em;
49 | clear: both;
50 | color: #333;
51 | }
52 |
53 | .login .form-row #id_username, .login .form-row #id_password {
54 | clear: both;
55 | padding: 8px;
56 | width: 100%;
57 | -webkit-box-sizing: border-box;
58 | -moz-box-sizing: border-box;
59 | box-sizing: border-box;
60 | }
61 |
62 | .login span.help {
63 | font-size: 10px;
64 | display: block;
65 | }
66 |
67 | .login .submit-row {
68 | clear: both;
69 | padding: 1em 0 0 9.4em;
70 | margin: 0;
71 | border: none;
72 | background: none;
73 | text-align: left;
74 | }
75 |
76 | .login .password-reset-link {
77 | text-align: center;
78 | }
79 |
--------------------------------------------------------------------------------
/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 | .module ul, .module ol {
34 | margin-left: 0;
35 | margin-right: 1.5em;
36 | }
37 |
38 | .addlink, .changelink {
39 | padding-left: 0;
40 | padding-right: 16px;
41 | background-position: 100% 1px;
42 | }
43 |
44 | .deletelink {
45 | padding-left: 0;
46 | padding-right: 16px;
47 | background-position: 100% 1px;
48 | }
49 |
50 | .object-tools {
51 | float: left;
52 | }
53 |
54 | thead th:first-child,
55 | tfoot td:first-child {
56 | border-left: none;
57 | }
58 |
59 | /* LAYOUT */
60 |
61 | #user-tools {
62 | right: auto;
63 | left: 0;
64 | text-align: left;
65 | }
66 |
67 | div.breadcrumbs {
68 | text-align: right;
69 | }
70 |
71 | #content-main {
72 | float: right;
73 | }
74 |
75 | #content-related {
76 | float: left;
77 | margin-left: -300px;
78 | margin-right: auto;
79 | }
80 |
81 | .colMS {
82 | margin-left: 300px;
83 | margin-right: 0;
84 | }
85 |
86 | /* SORTABLE TABLES */
87 |
88 | table thead th.sorted .sortoptions {
89 | float: left;
90 | }
91 |
92 | thead th.sorted .text {
93 | padding-right: 0;
94 | padding-left: 42px;
95 | }
96 |
97 | /* dashboard styles */
98 |
99 | .dashboard .module table td a {
100 | padding-left: .6em;
101 | padding-right: 16px;
102 | }
103 |
104 | /* changelists styles */
105 |
106 | .change-list .filtered table {
107 | border-left: none;
108 | border-right: 0px none;
109 | }
110 |
111 | #changelist-filter {
112 | right: auto;
113 | left: 0;
114 | border-left: none;
115 | border-right: none;
116 | }
117 |
118 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
119 | margin-right: 0;
120 | margin-left: 280px;
121 | }
122 |
123 | #changelist-filter li.selected {
124 | border-left: none;
125 | padding-left: 10px;
126 | margin-left: 0;
127 | border-right: 5px solid #eaeaea;
128 | padding-right: 10px;
129 | margin-right: -15px;
130 | }
131 |
132 | .filtered .actions {
133 | margin-left: 280px;
134 | margin-right: 0;
135 | }
136 |
137 | #changelist table tbody td:first-child, #changelist table tbody th:first-child {
138 | border-right: none;
139 | border-left: none;
140 | }
141 |
142 | /* FORMS */
143 |
144 | .aligned label {
145 | padding: 0 0 3px 1em;
146 | float: right;
147 | }
148 |
149 | .submit-row {
150 | text-align: left
151 | }
152 |
153 | .submit-row p.deletelink-box {
154 | float: right;
155 | }
156 |
157 | .submit-row input.default {
158 | margin-left: 0;
159 | }
160 |
161 | .vDateField, .vTimeField {
162 | margin-left: 2px;
163 | }
164 |
165 | .aligned .form-row input {
166 | margin-left: 5px;
167 | }
168 |
169 | form .aligned p.help, form .aligned div.help {
170 | clear: right;
171 | }
172 |
173 | form ul.inline li {
174 | float: right;
175 | padding-right: 0;
176 | padding-left: 7px;
177 | }
178 |
179 | input[type=submit].default, .submit-row input.default {
180 | float: left;
181 | }
182 |
183 | fieldset .field-box {
184 | float: right;
185 | margin-left: 20px;
186 | margin-right: 0;
187 | }
188 |
189 | .errorlist li {
190 | background-position: 100% 12px;
191 | padding: 0;
192 | }
193 |
194 | .errornote {
195 | background-position: 100% 12px;
196 | padding: 10px 12px;
197 | }
198 |
199 | /* WIDGETS */
200 |
201 | .calendarnav-previous {
202 | top: 0;
203 | left: auto;
204 | right: 10px;
205 | }
206 |
207 | .calendarnav-next {
208 | top: 0;
209 | right: auto;
210 | left: 10px;
211 | }
212 |
213 | .calendar caption, .calendarbox h2 {
214 | text-align: center;
215 | }
216 |
217 | .selector {
218 | float: right;
219 | }
220 |
221 | .selector .selector-filter {
222 | text-align: right;
223 | }
224 |
225 | .inline-deletelink {
226 | float: left;
227 | }
228 |
229 | form .form-row p.datetime {
230 | overflow: hidden;
231 | }
232 |
233 | .related-widget-wrapper {
234 | float: right;
235 | }
236 |
237 | /* MISC */
238 |
239 | .inline-related h2, .inline-group h2 {
240 | text-align: right
241 | }
242 |
243 | .inline-related h3 span.delete {
244 | padding-right: 20px;
245 | padding-left: inherit;
246 | left: 10px;
247 | right: inherit;
248 | float:left;
249 | }
250 |
251 | .inline-related h3 span.delete label {
252 | margin-left: inherit;
253 | margin-right: 2px;
254 | }
255 |
256 | /* IE7 specific bug fixes */
257 |
258 | div.colM {
259 | position: relative;
260 | }
261 |
262 | .submit-row input {
263 | float: left;
264 | }
265 |
--------------------------------------------------------------------------------
/static/admin/fonts/README.txt:
--------------------------------------------------------------------------------
1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto
2 | Weights used in this project: Light (300), Regular (400), Bold (700)
3 |
--------------------------------------------------------------------------------
/static/admin/fonts/Roboto-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/static/admin/fonts/Roboto-Bold-webfont.woff
--------------------------------------------------------------------------------
/static/admin/fonts/Roboto-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/static/admin/fonts/Roboto-Light-webfont.woff
--------------------------------------------------------------------------------
/static/admin/fonts/Roboto-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxinglong007/WAPI/65f0010f3e0ce22c510b54f236bb17938dccee5b/static/admin/fonts/Roboto-Regular-webfont.woff
--------------------------------------------------------------------------------
/static/admin/img/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Code Charm Ltd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/static/admin/img/README.txt:
--------------------------------------------------------------------------------
1 | All icons are taken from Font Awesome (http://fontawesome.io/) project.
2 | The Font Awesome font is licensed under the SIL OFL 1.1:
3 | - http://scripts.sil.org/OFL
4 |
5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG
6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license
7 | in current folder).
8 |
--------------------------------------------------------------------------------
/static/admin/img/calendar-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/static/admin/img/gis/move_vertex_off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/admin/img/gis/move_vertex_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/admin/img/icon-addlink.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-alert.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-calendar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/static/admin/img/icon-changelink.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-clock.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/static/admin/img/icon-deletelink.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-no.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-unknown-alt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-unknown.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/icon-yes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/inline-delete.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/search.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/selector-icons.svg:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/static/admin/img/sorting-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/static/admin/img/tooltag-add.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/img/tooltag-arrowright.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/static/admin/js/SelectBox.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | 'use strict';
3 | var SelectBox = {
4 | cache: {},
5 | init: function(id) {
6 | var box = document.getElementById(id);
7 | var node;
8 | SelectBox.cache[id] = [];
9 | var cache = SelectBox.cache[id];
10 | var boxOptions = box.options;
11 | var boxOptionsLength = boxOptions.length;
12 | for (var i = 0, j = boxOptionsLength; i < j; i++) {
13 | node = boxOptions[i];
14 | cache.push({value: node.value, text: node.text, displayed: 1});
15 | }
16 | },
17 | redisplay: function(id) {
18 | // Repopulate HTML select box from cache
19 | var box = document.getElementById(id);
20 | var node;
21 | $(box).empty(); // clear all options
22 | var new_options = box.outerHTML.slice(0, -9); // grab just the opening tag
23 | var cache = SelectBox.cache[id];
24 | for (var i = 0, j = cache.length; i < j; i++) {
25 | node = cache[i];
26 | if (node.displayed) {
27 | var new_option = new Option(node.text, node.value, false, false);
28 | // Shows a tooltip when hovering over the option
29 | new_option.setAttribute("title", node.text);
30 | new_options += new_option.outerHTML;
31 | }
32 | }
33 | new_options += '';
34 | box.outerHTML = new_options;
35 | },
36 | filter: function(id, text) {
37 | // Redisplay the HTML select box, displaying only the choices containing ALL
38 | // the words in text. (It's an AND search.)
39 | var tokens = text.toLowerCase().split(/\s+/);
40 | var node, token;
41 | var cache = SelectBox.cache[id];
42 | for (var i = 0, j = cache.length; i < j; i++) {
43 | node = cache[i];
44 | node.displayed = 1;
45 | var node_text = node.text.toLowerCase();
46 | var numTokens = tokens.length;
47 | for (var k = 0; k < numTokens; k++) {
48 | token = tokens[k];
49 | if (node_text.indexOf(token) === -1) {
50 | node.displayed = 0;
51 | break; // Once the first token isn't found we're done
52 | }
53 | }
54 | }
55 | SelectBox.redisplay(id);
56 | },
57 | delete_from_cache: function(id, value) {
58 | var node, delete_index = null;
59 | var cache = SelectBox.cache[id];
60 | for (var i = 0, j = cache.length; i < j; i++) {
61 | node = cache[i];
62 | if (node.value === value) {
63 | delete_index = i;
64 | break;
65 | }
66 | }
67 | cache.splice(delete_index, 1);
68 | },
69 | add_to_cache: function(id, option) {
70 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
71 | },
72 | cache_contains: function(id, value) {
73 | // Check if an item is contained in the cache
74 | var node;
75 | var cache = SelectBox.cache[id];
76 | for (var i = 0, j = cache.length; i < j; i++) {
77 | node = cache[i];
78 | if (node.value === value) {
79 | return true;
80 | }
81 | }
82 | return false;
83 | },
84 | move: function(from, to) {
85 | var from_box = document.getElementById(from);
86 | var option;
87 | var boxOptions = from_box.options;
88 | var boxOptionsLength = boxOptions.length;
89 | for (var i = 0, j = boxOptionsLength; i < j; i++) {
90 | option = boxOptions[i];
91 | var option_value = option.value;
92 | if (option.selected && SelectBox.cache_contains(from, option_value)) {
93 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
94 | SelectBox.delete_from_cache(from, option_value);
95 | }
96 | }
97 | SelectBox.redisplay(from);
98 | SelectBox.redisplay(to);
99 | },
100 | move_all: function(from, to) {
101 | var from_box = document.getElementById(from);
102 | var option;
103 | var boxOptions = from_box.options;
104 | var boxOptionsLength = boxOptions.length;
105 | for (var i = 0, j = boxOptionsLength; i < j; i++) {
106 | option = boxOptions[i];
107 | var option_value = option.value;
108 | if (SelectBox.cache_contains(from, option_value)) {
109 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
110 | SelectBox.delete_from_cache(from, option_value);
111 | }
112 | }
113 | SelectBox.redisplay(from);
114 | SelectBox.redisplay(to);
115 | },
116 | sort: function(id) {
117 | SelectBox.cache[id].sort(function(a, b) {
118 | a = a.text.toLowerCase();
119 | b = b.text.toLowerCase();
120 | try {
121 | if (a > b) {
122 | return 1;
123 | }
124 | if (a < b) {
125 | return -1;
126 | }
127 | }
128 | catch (e) {
129 | // silently fail on IE 'unknown' exception
130 | }
131 | return 0;
132 | } );
133 | },
134 | select_all: function(id) {
135 | var box = document.getElementById(id);
136 | var boxOptions = box.options;
137 | var boxOptionsLength = boxOptions.length;
138 | for (var i = 0; i < boxOptionsLength; i++) {
139 | boxOptions[i].selected = 'selected';
140 | }
141 | }
142 | };
143 | window.SelectBox = SelectBox;
144 | })(django.jQuery);
145 |
--------------------------------------------------------------------------------
/static/admin/js/actions.js:
--------------------------------------------------------------------------------
1 | /*global gettext, interpolate, ngettext*/
2 | (function($) {
3 | 'use strict';
4 | var lastChecked;
5 |
6 | $.fn.actions = function(opts) {
7 | var options = $.extend({}, $.fn.actions.defaults, opts);
8 | var actionCheckboxes = $(this);
9 | var list_editable_changed = false;
10 | var showQuestion = function() {
11 | $(options.acrossClears).hide();
12 | $(options.acrossQuestions).show();
13 | $(options.allContainer).hide();
14 | },
15 | showClear = function() {
16 | $(options.acrossClears).show();
17 | $(options.acrossQuestions).hide();
18 | $(options.actionContainer).toggleClass(options.selectedClass);
19 | $(options.allContainer).show();
20 | $(options.counterContainer).hide();
21 | },
22 | reset = function() {
23 | $(options.acrossClears).hide();
24 | $(options.acrossQuestions).hide();
25 | $(options.allContainer).hide();
26 | $(options.counterContainer).show();
27 | },
28 | clearAcross = function() {
29 | reset();
30 | $(options.acrossInput).val(0);
31 | $(options.actionContainer).removeClass(options.selectedClass);
32 | },
33 | checker = function(checked) {
34 | if (checked) {
35 | showQuestion();
36 | } else {
37 | reset();
38 | }
39 | $(actionCheckboxes).prop("checked", checked)
40 | .parent().parent().toggleClass(options.selectedClass, checked);
41 | },
42 | updateCounter = function() {
43 | var sel = $(actionCheckboxes).filter(":checked").length;
44 | // data-actions-icnt is defined in the generated HTML
45 | // and contains the total amount of objects in the queryset
46 | var actions_icnt = $('.action-counter').data('actionsIcnt');
47 | $(options.counterContainer).html(interpolate(
48 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
49 | sel: sel,
50 | cnt: actions_icnt
51 | }, true));
52 | $(options.allToggle).prop("checked", function() {
53 | var value;
54 | if (sel === actionCheckboxes.length) {
55 | value = true;
56 | showQuestion();
57 | } else {
58 | value = false;
59 | clearAcross();
60 | }
61 | return value;
62 | });
63 | };
64 | // Show counter by default
65 | $(options.counterContainer).show();
66 | // Check state of checkboxes and reinit state if needed
67 | $(this).filter(":checked").each(function(i) {
68 | $(this).parent().parent().toggleClass(options.selectedClass);
69 | updateCounter();
70 | if ($(options.acrossInput).val() === 1) {
71 | showClear();
72 | }
73 | });
74 | $(options.allToggle).show().click(function() {
75 | checker($(this).prop("checked"));
76 | updateCounter();
77 | });
78 | $("a", options.acrossQuestions).click(function(event) {
79 | event.preventDefault();
80 | $(options.acrossInput).val(1);
81 | showClear();
82 | });
83 | $("a", options.acrossClears).click(function(event) {
84 | event.preventDefault();
85 | $(options.allToggle).prop("checked", false);
86 | clearAcross();
87 | checker(0);
88 | updateCounter();
89 | });
90 | lastChecked = null;
91 | $(actionCheckboxes).click(function(event) {
92 | if (!event) { event = window.event; }
93 | var target = event.target ? event.target : event.srcElement;
94 | if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {
95 | var inrange = false;
96 | $(lastChecked).prop("checked", target.checked)
97 | .parent().parent().toggleClass(options.selectedClass, target.checked);
98 | $(actionCheckboxes).each(function() {
99 | if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {
100 | inrange = (inrange) ? false : true;
101 | }
102 | if (inrange) {
103 | $(this).prop("checked", target.checked)
104 | .parent().parent().toggleClass(options.selectedClass, target.checked);
105 | }
106 | });
107 | }
108 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked);
109 | lastChecked = target;
110 | updateCounter();
111 | });
112 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
113 | list_editable_changed = true;
114 | });
115 | $('form#changelist-form button[name="index"]').click(function(event) {
116 | if (list_editable_changed) {
117 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
118 | }
119 | });
120 | $('form#changelist-form input[name="_save"]').click(function(event) {
121 | var action_changed = false;
122 | $('select option:selected', options.actionContainer).each(function() {
123 | if ($(this).val()) {
124 | action_changed = true;
125 | }
126 | });
127 | if (action_changed) {
128 | if (list_editable_changed) {
129 | 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."));
130 | } else {
131 | 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."));
132 | }
133 | }
134 | });
135 | };
136 | /* Setup plugin defaults */
137 | $.fn.actions.defaults = {
138 | actionContainer: "div.actions",
139 | counterContainer: "span.action-counter",
140 | allContainer: "div.actions span.all",
141 | acrossInput: "div.actions input.select-across",
142 | acrossQuestions: "div.actions span.question",
143 | acrossClears: "div.actions span.clear",
144 | allToggle: "#action-toggle",
145 | selectedClass: "selected"
146 | };
147 | $(document).ready(function() {
148 | var $actionsEls = $('tr input.action-select');
149 | if ($actionsEls.length > 0) {
150 | $actionsEls.actions();
151 | }
152 | });
153 | })(django.jQuery);
154 |
--------------------------------------------------------------------------------
/static/admin/js/actions.min.js:
--------------------------------------------------------------------------------
1 | (function(a){var f;a.fn.actions=function(e){var b=a.extend({},a.fn.actions.defaults,e),g=a(this),k=!1,l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},n=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},p=function(){n();
2 | a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},q=function(c){c?l():n();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length,d=a(".action-counter").data("actionsIcnt");a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:d},!0));a(b.allToggle).prop("checked",function(){var a;c===g.length?(a=!0,l()):(a=!1,p());return a})};a(b.counterContainer).show();
3 | a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);h();1===a(b.acrossInput).val()&&m()});a(b.allToggle).show().click(function(){q(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);p();q(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&
4 | a.data(f)!==a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,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(){k=!0});a('form#changelist-form button[name="index"]').click(function(a){if(k)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 k?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"};a(document).ready(function(){var e=a("tr input.action-select");0' + gettext("Show") +
11 | ')');
12 | }
13 | });
14 | // Add toggle to anchor tag
15 | $("fieldset.collapse a.collapse-toggle").click(function(ev) {
16 | if ($(this).closest("fieldset").hasClass("collapsed")) {
17 | // Show
18 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
19 | } else {
20 | // Hide
21 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
22 | }
23 | return false;
24 | });
25 | });
26 | })(django.jQuery);
27 |
--------------------------------------------------------------------------------
/static/admin/js/collapse.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(b,c){0===a(c).find("div.errors").length&&a(c).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+" )")});a("fieldset.collapse a.collapse-toggle").click(function(b){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!1})})})(django.jQuery);
3 |
--------------------------------------------------------------------------------
/static/admin/js/inlines.min.js:
--------------------------------------------------------------------------------
1 | (function(c){c.fn.formset=function(b){var a=c.extend({},c.fn.formset.defaults,b),d=c(this);b=d.parent();var k=function(a,g,l){var b=new RegExp("("+g+"-(\\d+|__prefix__))");g=g+"-"+l;c(a).prop("for")&&c(a).prop("for",c(a).prop("for").replace(b,g));a.id&&(a.id=a.id.replace(b,g));a.name&&(a.name=a.name.replace(b,g))},e=c("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(e.val(),10),g=c("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),h=""===g.val()||0'+a.addText+" "),m=b.find("tr:last a")):(d.filter(":last").after('"),m=d.filter(":last").next().find("a")));m.click(function(b){b.preventDefault();b=c("#"+a.prefix+"-empty");
3 | var f=b.clone(!0);f.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);f.is("tr")?f.children(":last").append('"):f.is("ul")||f.is("ol")?f.append(''+a.deleteText+" "):f.children(":first").append(''+a.deleteText+" ");f.find("*").each(function(){k(this,a.prefix,e.val())});f.insertBefore(c(b));
4 | c(e).val(parseInt(e.val(),10)+1);l+=1;""!==g.val()&&0>=g.val()-e.val()&&m.parent().hide();f.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();f.remove();--l;a.removed&&a.removed(f);c(document).trigger("formset:removed",[f,a.prefix]);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===g.val()||0 0) {
26 | values.push(field.val());
27 | }
28 | });
29 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode));
30 | };
31 |
32 | prepopulatedField.data('_changed', false);
33 | prepopulatedField.change(function() {
34 | prepopulatedField.data('_changed', true);
35 | });
36 |
37 | if (!prepopulatedField.val()) {
38 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate);
39 | }
40 | });
41 | };
42 | })(django.jQuery);
43 |
--------------------------------------------------------------------------------
/static/admin/js/prepopulate.min.js:
--------------------------------------------------------------------------------
1 | (function(c){c.fn.prepopulate=function(e,f,g){return this.each(function(){var a=c(this),b=function(){if(!a.data("_changed")){var b=[];c.each(e,function(a,d){d=c(d);0
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/static/djcelery/style.css:
--------------------------------------------------------------------------------
1 | .form-row.field-traceback p {
2 | font-family: monospace;
3 | white-space: pre;
4 | }
5 |
--------------------------------------------------------------------------------
/templates/hostconfig.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | hosts 文件修改
4 |
19 |
20 |
--------------------------------------------------------------------------------