Showing preview only (3,374K chars total). Download the full file or copy to clipboard to get everything.
Repository: radiateboy/automagic
Branch: master
Commit: 2c0f40bf9dad
Files: 213
Total size: 3.2 MB
Directory structure:
gitextract_402wqmeg/
├── Dockerfile
├── LICENSE
├── README.md
├── auto_auth/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations/
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── automatic/
│ ├── __init__.py
│ ├── asgi.py
│ ├── element/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── keywords/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── fixtures/
│ │ │ └── initial_data.json
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── management/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── settings/
│ │ ├── __init__.py
│ │ └── common.py
│ ├── signals.py
│ ├── static/
│ │ ├── css/
│ │ │ ├── ak-base-style.css
│ │ │ ├── ak-schedule.css
│ │ │ ├── bootstrap-theme.css
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrapValidator.css
│ │ │ ├── font-awesome/
│ │ │ │ ├── css/
│ │ │ │ │ ├── font-awesome-ie7.css
│ │ │ │ │ └── font-awesome.css
│ │ │ │ ├── font/
│ │ │ │ │ └── FontAwesome.otf
│ │ │ │ ├── fonts/
│ │ │ │ │ └── FontAwesome.otf
│ │ │ │ ├── less/
│ │ │ │ │ ├── animated.less
│ │ │ │ │ ├── bootstrap.less
│ │ │ │ │ ├── bordered-pulled.less
│ │ │ │ │ ├── core.less
│ │ │ │ │ ├── extras.less
│ │ │ │ │ ├── fixed-width.less
│ │ │ │ │ ├── font-awesome-ie7.less
│ │ │ │ │ ├── font-awesome.less
│ │ │ │ │ ├── icons.less
│ │ │ │ │ ├── larger.less
│ │ │ │ │ ├── list.less
│ │ │ │ │ ├── mixins.less
│ │ │ │ │ ├── path.less
│ │ │ │ │ ├── rotated-flipped.less
│ │ │ │ │ ├── stacked.less
│ │ │ │ │ └── variables.less
│ │ │ │ └── scss/
│ │ │ │ ├── _animated.scss
│ │ │ │ ├── _bootstrap.scss
│ │ │ │ ├── _bordered-pulled.scss
│ │ │ │ ├── _core.scss
│ │ │ │ ├── _extras.scss
│ │ │ │ ├── _fixed-width.scss
│ │ │ │ ├── _icons.scss
│ │ │ │ ├── _larger.scss
│ │ │ │ ├── _list.scss
│ │ │ │ ├── _mixins.scss
│ │ │ │ ├── _path.scss
│ │ │ │ ├── _rotated-flipped.scss
│ │ │ │ ├── _stacked.scss
│ │ │ │ ├── _variables.scss
│ │ │ │ ├── font-awesome-ie7.scss
│ │ │ │ └── font-awesome.scss
│ │ │ ├── font-awesome.css
│ │ │ ├── jquery-ui.css
│ │ │ ├── login-app.css
│ │ │ ├── login-vendor.css
│ │ │ ├── page-v3/
│ │ │ │ ├── ak-master-page-v3.css
│ │ │ │ └── ak-master-page-v3style.css
│ │ │ └── wheelmenu.css
│ │ ├── js/
│ │ │ ├── automagic.js
│ │ │ ├── back-to-top.js
│ │ │ ├── bootstrapValidator.js
│ │ │ ├── casemanage.js
│ │ │ ├── common.js
│ │ │ ├── jquery-ui.js
│ │ │ ├── jquery.wheelmenu.js
│ │ │ ├── keyword.js
│ │ │ └── taskmanage.js
│ │ ├── muti_select/
│ │ │ ├── css/
│ │ │ │ ├── multi.css
│ │ │ │ └── style.css
│ │ │ └── src/
│ │ │ └── MultiSelectDropList.js
│ │ └── zTree_v3/
│ │ ├── css/
│ │ │ ├── awesomeStyle/
│ │ │ │ ├── awesome.css
│ │ │ │ ├── awesome.less
│ │ │ │ └── fa.less
│ │ │ ├── demo.css
│ │ │ ├── metroStyle/
│ │ │ │ └── metroStyle.css
│ │ │ └── zTreeStyle/
│ │ │ └── zTreeStyle.css
│ │ └── js/
│ │ ├── jquery.ztree.all.js
│ │ ├── jquery.ztree.core.js
│ │ ├── jquery.ztree.excheck.js
│ │ ├── jquery.ztree.exedit.js
│ │ └── jquery.ztree.exhide.js
│ ├── templates/
│ │ ├── 404.html
│ │ ├── 500.html
│ │ ├── base.html
│ │ ├── comingsoon.html
│ │ ├── element/
│ │ │ └── element.html
│ │ ├── frame.html
│ │ ├── index.html
│ │ ├── keywords/
│ │ │ └── keyword.html
│ │ ├── management/
│ │ │ ├── moduleadd.html
│ │ │ ├── moduleview.html
│ │ │ ├── productadd.html
│ │ │ ├── productlist.html
│ │ │ ├── productview.html
│ │ │ ├── projectadd.html
│ │ │ ├── projectlist.html
│ │ │ ├── projectview.html
│ │ │ └── syslog.html
│ │ ├── nav.html
│ │ ├── oauth/
│ │ │ └── userlist.html
│ │ ├── registration/
│ │ │ └── login.html
│ │ ├── testcase/
│ │ │ ├── caseadd.html
│ │ │ ├── casecopy.html
│ │ │ ├── caseedit.html
│ │ │ ├── caselist.html
│ │ │ └── caseview.html
│ │ ├── testtask/
│ │ │ ├── taskadd.html
│ │ │ ├── taskedit.html
│ │ │ └── tasklist.html
│ │ └── webinterface/
│ │ └── webinterface.html
│ ├── testcase/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── forms.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── testtask/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── urls.py
│ ├── webinterface/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── migrations/
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ └── wsgi.py
├── docker-compose.yml
├── init.sh
├── insertkeyword.sql
├── manage.py
├── requirements/
│ ├── base.txt
│ └── seleniumreq.txt
├── seleniumkeyword/
│ ├── AddCase.py
│ ├── Base.py
│ ├── CustomKeyword.py
│ ├── HTMLTestRunner.py
│ ├── README.MD
│ ├── RestApiUtil.py
│ ├── SimulatorUtil.py
│ ├── TestSuite.py
│ ├── __init__.py
│ ├── data/
│ │ └── readme.md
│ ├── mwupgrade.py
│ ├── popautomagic.py
│ ├── result/
│ │ └── highcharts.js
│ ├── sendlog/
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── guitest.py
│ │ ├── mysetup.py
│ │ ├── randip.py
│ │ ├── randomip.py
│ │ ├── send.config
│ │ ├── sendingdata.py
│ │ ├── syslogc.py
│ │ ├── tcpsendingsyslog.py
│ │ ├── tcpsendtest.py
│ │ ├── udpsendingsyslog.py
│ │ └── weighted_choice.py
│ ├── settings.py
│ ├── testrail.py
│ └── testraildemo.py
└── start.py
================================================
FILE CONTENTS
================================================
================================================
FILE: Dockerfile
================================================
FROM ubuntu:18.04
MAINTAINER ray<tsbc@vip.qq.com>
LABEL version="2.0" by="ray" descriptio="python3.6 django 3.2.3"
ENV TZ=Asia/Shanghai
ENV PATH=/usr/bin:$PATH
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG C.UTF-8
RUN mkdir /opt/automagic
WORKDIR /opt/automagic
RUN set -x;apt-get update \
&& apt-get install -y vim \
&& apt-get install -y tzdata \
&& apt-get install -y python3 \
&& apt-get install -y python3-pip \
&& pip3 install --upgrade pip
COPY . /opt/automagic
RUN pip3 --no-cache-dir install -r /opt/automagic/requirements/base.txt \
-i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
RUN pip3 --no-cache-dir install -r /opt/automagic/requirements/seleniumreq.txt \
-i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
ENTRYPOINT ["python3","start.py"]
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., [http://fsf.org/]
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) 2018 tsbc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
================================================
FILE: README.md
================================================
# 自动化测试平台
## python3.8+ Django 3.2.10框架
>python3.8以下版本 使用Django 3.0.5 以上版本 ,django的 /admin/后台会异常退出,不使用/admin/后台不影响,安装请注意版本
### [新用户指导使用指南](https://github.com/radiateboy/automagic/wiki)
# (一)源码安装
> pip3 install -r requirements/base.txt
>
> pip3 install -r requirements/seleniumreq.txt
### Mysql/Mariadb 数据库 automatic/settings/common.py
```python
MYSQL_USERNAME = os.environ.get('MYSQL_USERNAME', 'root')
MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', '123456')
MYSQL_HOST = os.environ.get('MYSQL_HOST', 'localhost')
MYSQL_PORT = os.environ.get('MYSQL_PORT', '3306')
MYSQL_DBNAME = os.environ.get('MYSQL_DBNAME', 'automatic')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': MYSQL_DBNAME,
'USER': MYSQL_USERNAME,
'PASSWORD': MYSQL_PASSWORD,
'HOST': MYSQL_HOST,
'PORT': MYSQL_PORT,
}
}
```
#### 初始化并启动服务
```shell
python3 start.py
```
另:内置关键字 在wiki #关键字创建# 页面(可以了解一下)
_http://127.0.0.1:8000_ 访问登录即可
默认管理员用户:admin, 密码:admin@123
# (二)docker安装
## 方法一: 命令安装启动
```shell script
docker pull tsbc520/automagic:2.0
```
启动docker容器:
```shell script
docker run -d -p 8000:8000 \
-e MYSQL_HOST=192.168.10.167 \
-e MYSQL_PORT=3306 \
-e MYSQL_DBNAME=automatic \
-e MYSQL_USERNAME=root \
-e MYSQL_PASSWORD=123456 \
tsbc520/automagic:2.0
```
## 方法二: docker-compose
```shell script
docker-compose up
```
## 如何执行测试脚本
[点击查看如何执行测试](https://github.com/radiateboy/automagic/wiki/Seleniumkeyword%E4%BB%8B%E7%BB%8D)
## 公众号
扫一扫关注公众号

================================================
FILE: auto_auth/__init__.py
================================================
================================================
FILE: auto_auth/admin.py
================================================
from django.contrib import admin
# Register your models here.
================================================
FILE: auto_auth/apps.py
================================================
from django.apps import AppConfig
class AutoAuthConfig(AppConfig):
name = 'auto_auth'
================================================
FILE: auto_auth/forms.py
================================================
# -*- coding: utf-8 -*-
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.utils.translation import ugettext_lazy as _
from auto_auth.models import UserActivationKey
class RegistrationForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ("username",)
def clean_email(self):
email = self.cleaned_data['email']
try:
User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError(
_("A user with that email already exists."))
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.is_active = False
user.set_password(self.cleaned_data["password1"])
if User.objects.filter(is_superuser=True).count() == 0:
user.is_superuser = True
if commit:
user.save()
# initiate_user_with_default_setups(user)
return user
def set_activation_key(self):
return UserActivationKey.set_random_key_for_user(user=self.instance)
================================================
FILE: auto_auth/migrations/0001_initial.py
================================================
# Generated by Django 3.0.2 on 2020-01-15 10:02
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0011_update_proxy_permissions'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('realname', models.CharField(blank=True, max_length=50, null=True, verbose_name='真实姓名')),
('mobile', models.CharField(blank=True, max_length=11, null=True, verbose_name='电话号码')),
('email', models.EmailField(max_length=255, unique=True, verbose_name='邮箱')),
('dept', models.CharField(choices=[('测试', '测试'), ('开发', '开发')], default='测试', max_length=100, verbose_name='部门')),
('is_active', models.BooleanField(default=True, verbose_name='激活状态')),
('is_admin', models.BooleanField(default=False, verbose_name='是否管理员')),
('testrailuser', models.CharField(blank=True, max_length=50, null=True, verbose_name='TestRail用户名')),
('testrailpass', models.CharField(blank=True, max_length=50, null=True, verbose_name='TestRail密码')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='UserActivationKey',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('activation_key', models.CharField(blank=True, max_length=64, null=True)),
('key_expires', models.DateTimeField(blank=True, null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
================================================
FILE: auto_auth/migrations/__init__.py
================================================
================================================
FILE: auto_auth/models.py
================================================
# -*- coding: utf-8 -*-
import datetime
import secrets
from django.db import models
from django.conf import settings
from django.contrib.auth.models import BaseUserManager, AbstractUser
class UserActivationKey(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
activation_key = models.CharField(max_length=64, null=True, blank=True)
key_expires = models.DateTimeField(null=True, blank=True)
@classmethod
def set_random_key_for_user(cls, user, force=False):
activation_key = secrets.token_hex()
# Create and save their profile
user_activation_key, created = cls.objects.get_or_create(user=user)
if created or force:
user_activation_key.activation_key = activation_key
user_activation_key.key_expires = datetime.datetime.today() + datetime.timedelta(7)
user_activation_key.save()
return user_activation_key
class MyUserManager(BaseUserManager):
# def current_time(self):
# """get current time """
# from datetime import datetime
# return datetime.now().strftime("%Y-%m-%d")
def create_user(self, username, email, password):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not username:
raise ValueError('username is unique')
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email, password):
"""
Creates and saves a superuser with the given email, password.
"""
user = self.create_user(username, email, password)
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
class User(AbstractUser):
Dept_Choice = (
('测试', '测试'),
('开发', '开发'),
)
realname = models.CharField(max_length=50, verbose_name="真实姓名", null=True, blank=True, editable=True)
mobile = models.CharField(max_length=11, verbose_name="电话号码", null=True, blank=True, editable=True)
email = models.EmailField(verbose_name='邮箱', max_length=255, unique=True)
dept = models.CharField(verbose_name=u'部门', choices=Dept_Choice, default='测试', max_length=100)
is_active = models.BooleanField(default=True, verbose_name='激活状态')
is_admin = models.BooleanField(default=False, verbose_name='是否管理员')
testrailuser = models.CharField(max_length=50, verbose_name="TestRail用户名", null=True, blank=True, editable=True)
testrailpass = models.CharField(max_length=50, verbose_name="TestRail密码", null=True, blank=True, editable=True)
def get_full_name(self):
# The user is identified by their email address
return self.username
def get_short_name(self):
# The user is identified by their email address
return self.username
def __unicode__(self): # __unicode__ on Python 2
return self.username
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
================================================
FILE: auto_auth/tests.py
================================================
from django.test import TestCase
# Create your tests here.
================================================
FILE: auto_auth/urls.py
================================================
# -*- coding: utf-8 -*-
from django.conf.urls import url
from django.urls import reverse_lazy
from django.contrib.auth import views as contrib_auth_views
from django.contrib.auth.decorators import login_required
from auto_auth import views
urlpatterns = [
url(r'^(?P<username>[\w.@+-]+)/profile/$', views.profile,
name='auto-profile'),
url(r'^register/$', views.register, name='auto-register'),
url(r'^confirm/(?P<activation_key>[A-Za-z0-9\-]+)/$', views.confirm,
name='auto-confirm'),
url(r'^user/add/$', views.add_user, name='adduser'),
url(r'^user/list/$', login_required(views.UserListIndex.as_view()), name='userlist'),
url(r'^user/update/$', views.update_user, name='userupdate'),
url(r'^user/del/(?P<id>\d+)/$', views.del_user, name='userdel'),
url(r'^setedit/user/$', views.set_edit_user, name='setedituser'),
url(r'^login/$', views.LoginViewWithCustomTemplate.as_view(), name='auto-login'),
url(r'^logout/$',
contrib_auth_views.LogoutView.as_view(next_page=reverse_lazy('auto-login')),
name='auto-logout'),
url(r'^passwordreset/$', contrib_auth_views.PasswordResetView.as_view(),
name='auto-password_reset'),
url(r'^passwordreset/done/$', contrib_auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
url(r'^passwordreset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
contrib_auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
url(r'^passwordreset/complete/$',
contrib_auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
================================================
FILE: auto_auth/views.py
================================================
# -*- coding: utf-8 -*-
import json
from datetime import datetime
from django.urls import reverse
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import views
from django.views.decorators.http import require_GET
from django.utils.translation import ugettext_lazy as _
# from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout, authenticate, login
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect
from django.contrib.auth.hashers import make_password
from django.views.generic import ListView
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q
from auto_auth.models import User
from automatic.management.models import Product, UserAndProduct
from automatic.signals import USER_REGISTERED_SIGNAL
from auto_auth.forms import RegistrationForm
from auto_auth.models import UserActivationKey
class LoginViewWithCustomTemplate(views.LoginView):
def get_template_names(self):
return ['registration/custom_login.html', 'registration/login.html']
@login_required()
def index(request):
return render(request, 'index.html')
def register(request):
"""Register method of account"""
if request.method == 'POST':
form = RegistrationForm(data=request.POST, files=request.FILES)
if form.is_valid():
new_user = form.save()
activation_key = form.set_activation_key()
# send a signal that new user has been registered
USER_REGISTERED_SIGNAL.send(sender=form.__class__,
request=request,
user=new_user)
# Send confirmation email to new user
if settings.DEFAULT_FROM_EMAIL and settings.AUTO_APPROVE_NEW_USERS:
form.send_confirm_mail(request, activation_key)
messages.add_message(
request,
messages.SUCCESS,
_('Your account has been created, please check your mailbox for confirmation')
)
else:
messages.add_message(
request,
messages.WARNING,
_('Your account has been created, but you need an administrator to activate it')
)
messages.add_message(
request,
messages.INFO,
_('Following is the administrator list')
)
# super-users can approve others
for user in User.objects.filter(is_superuser=True):
messages.add_message(
request,
messages.INFO,
'<a href="mailto:{}">{}</a>'.format(user.email,
user.get_full_name() or user.username)
)
# site admins should be able to do so too
for name, email in settings.ADMINS:
messages.add_message(
request,
messages.WARNING,
'<a href="mailto:{}">{}</a>'.format(email, name)
)
return HttpResponseRedirect(reverse('core-views-index'))
else:
form = RegistrationForm()
context_data = {
'form': form,
}
return render(request, 'registration/registration_form.html', context_data)
@require_GET
def confirm(request, activation_key):
"""Confirm the user registration"""
# Get the object
try:
_activation_key = UserActivationKey.objects.select_related('user')
_activation_key = _activation_key.get(activation_key=activation_key)
except UserActivationKey.DoesNotExist:
messages.add_message(
request,
messages.ERROR,
_('This activation key no longer exists in the database')
)
return HttpResponseRedirect(request.GET.get('next', reverse('core-views-index')))
if _activation_key.key_expires <= datetime.now():
messages.add_message(request, messages.ERROR, _('This activation key has expired'))
return HttpResponseRedirect(request.GET.get('next', reverse('core-views-index')))
# All thing done, start to active the user and use the user login
user = _activation_key.user
user.is_active = True
user.save(update_fields=['is_active'])
_activation_key.delete()
messages.add_message(
request,
messages.SUCCESS,
_('Your account has been activated successfully')
)
return HttpResponseRedirect(request.GET.get('next', reverse('core-views-index')))
def profile(request, username):
"""Show user profiles"""
user = get_object_or_404(User, username=username)
return HttpResponseRedirect(reverse('admin:auth_user_change', args=[user.pk]))
def verify(request, query_dict):
"""验证用户名密码"""
user = authenticate(username=query_dict["username"], password=query_dict["password"])
if user is not None:
login(request, user)
return "verify_success"
else:
return u"用户名密码错误"
def login_page(request):
if request.method == "POST":
return HttpResponse(verify(request, request.POST))
return render(request, "registration/login.html")
def _logout(request):
logout(request)
return redirect("/login")
@csrf_exempt
@login_required()
def add_user(request):
if request.method == 'POST':
post_dict = request.POST
user_dict = {"username": post_dict['username'],
"realname": post_dict['realname'],
"password":post_dict['password'],
"email": post_dict['email'],
"mobile": post_dict['mobile'],
"dept": post_dict['dept'],
"testrailuser": post_dict['testrailuser'] if 'testrailuser' in post_dict else None,
"testrailpass": post_dict['testrailpass'] if 'testrailpass' in post_dict else None,
}
if 'is_admin' in post_dict:
is_admin = True
is_staff = True
else:
is_admin = False
is_staff = False
if 'is_active' in post_dict:
is_active = True
else:
is_active = False
username = user_dict.get('username')
password = make_password(user_dict.get('password'), None, 'pbkdf2_sha256')
realname = user_dict.get('realname')
email = user_dict.get('email')
mobile = user_dict.get('mobile')
dept = user_dict.get('dept')
# is_admin = is_admin
# is_active = is_active
testrailuser = user_dict.get('testrailuser')
testrailpass = user_dict.get('testrailpass')
# print username,password,realname,email,mobile,is_admin,is_active,testrailuser,testrailpass
try:
User.objects.get(username=username).username
return HttpResponse('用户名已经存在')
except:
pass
try:
User.objects.get(email=email).email
return HttpResponse('邮箱地址已经被注册')
except:
pass
user = User(username=username, password=password, realname=realname, email=email, mobile=mobile, dept=dept,
is_active=is_active, is_admin=is_admin, is_staff=is_staff,
testrailuser=testrailuser, testrailpass=testrailpass)
user.save()
return HttpResponse('创建成功')
else:
return HttpResponse('创建失败')
@csrf_exempt
@login_required()
def update_user(request):
if request.method == 'POST':
post_dict = request.POST
user_dict = {"userid":post_dict['userid'],
"username": post_dict['username'],
"password": post_dict['password'],
"email":post_dict['email'],
"mobile": post_dict['mobile'],
"dept": post_dict['dept'],
"realname": post_dict['realname'],
"testrailuser": post_dict['testrailuser'] if 'testrailuser' in post_dict else None,
"testrailpass": post_dict['testrailpass'] if 'testrailpass' in post_dict else None,
}
if 'is_admin' in post_dict:
is_admin = True
is_staff = True
else:
is_admin = False
is_staff = False
if 'is_active' in post_dict:
is_active = True
else:
is_active = False
userid = user_dict.get('userid')
username = user_dict.get('username')
realname = user_dict.get('realname')
email = user_dict.get('email')
mobile = user_dict.get('mobile')
dept_str = user_dict.get('dept')
dept = dept_str if dept_str else '测试'
# is_admin = is_admin
# is_active = is_active
testrailuser = user_dict.get('testrailuser')
testrailpass = user_dict.get('testrailpass')
# updatetime = timezone.now()
u = User.objects.filter(id=int(userid))
# passwd = user_dict.get('password')
if user_dict.get('password') == '':
# print "AAA",username,user_dict.get('password')
u.update(username=username, realname=realname, email=email,mobile=mobile, dept=dept,is_active=is_active,
is_admin=is_admin, is_staff=is_staff, testrailuser=testrailuser,testrailpass=testrailpass)
else:
# print "BBB", username, user_dict.get('password')
password = make_password(user_dict.get('password'), None, 'pbkdf2_sha256')
u.update(username=username, password=password, realname=realname, dept=dept, email=email, mobile=mobile, is_active=is_active,
is_admin=is_admin, testrailuser=testrailuser, testrailpass=testrailpass)
return HttpResponse('修改成功')
else:
return HttpResponse('修改失败')
@csrf_exempt
def del_user(request,id):
user = get_object_or_404(User, pk=int(id))
user.delete()
return HttpResponseRedirect(reverse('userlist'))
@csrf_exempt
@login_required()
def set_edit_user(request):
userid = request.GET['userid']
user = User.objects.get(pk=userid)
userinfo = {}
userinfo['id'] = user.pk
userinfo['username'] = user.username
userinfo['password'] = user.password
userinfo['email'] = user.email
userinfo['mobile'] = user.mobile
userinfo['is_admin'] = user.is_admin
userinfo['is_staff'] = user.is_staff
userinfo['is_active'] = user.is_active
userinfo['realname'] = user.realname
userinfo['dept'] = user.dept
userinfo['testrailuser'] = user.testrailuser
userinfo['testrailpass'] = user.testrailpass
userlist = [userinfo]
return HttpResponse(json.dumps(userlist))
class UserListIndex(ListView):
context_object_name = 'userlist'
template_name = 'oauth/userlist.html'
paginate_by = 10
model = User
usersum = 0
http_method_names = [u'get']
alluser=[]
def get_queryset(self):
userlist = User.objects.all().order_by('-pk')
self.alluser = User.objects.filter(is_active='True')
keyword = self.request.GET.get('keyword')
if keyword:
userlist = userlist.filter(Q(username__icontains=keyword)|Q(email__icontains=keyword)|Q(mobile__icontains=keyword))
self.usersum = len(userlist)
return userlist
def get_context_data(self, **kwargs):
context = super(UserListIndex,self).get_context_data(**kwargs)
# userlist = User.objects.values('username').annotate()
context['productlist'] = Product.objects.all().order_by('-sortby')
context['userandproduct'] = UserAndProduct.objects.all()
context['usersum'] = self.usersum
context['alluser']=self.alluser
return context
================================================
FILE: automatic/__init__.py
================================================
# -*- coding: utf-8 -*-
__version__ = '2.0'
import pymysql
pymysql.install_as_MySQLdb()
================================================
FILE: automatic/asgi.py
================================================
"""
ASGI config for automatic project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'automatic.settings.common')
application = get_asgi_application()
================================================
FILE: automatic/element/__init__.py
================================================
================================================
FILE: automatic/element/admin.py
================================================
from django.contrib import admin
# Register your models here.
from automatic.element import models
class ElementAdmin(admin.ModelAdmin):
list_display = (id, 'descr', 'projectid', 'moduleid', 'locmode', 'location', 'createat', 'createtime', 'updateat', 'updatetime')
search_fields = ('keyword', 'kwdescr')
admin.site.register(models.Element, ElementAdmin)
================================================
FILE: automatic/element/apps.py
================================================
from django.apps import AppConfig
class ElementConfig(AppConfig):
name = 'automatic.element'
================================================
FILE: automatic/element/forms.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-08
"""
from django import forms
from automatic.element.models import Element
from django.forms import ModelForm, Textarea, Select, TextInput
class FormElement(forms.ModelForm):
class Meta:
model = Element
fields = ('descr','projectid','moduleid','locmode','location')
widgets = {'locmode': Select(attrs={'class':'ak-left ac-aselect','required':''}),
'descr':TextInput(attrs={'class':'form-control','placeholder':'请输入元素描述','required':''}),
'location': TextInput(attrs={'class': 'form-control','placeholder':'(如:id_username)','required':''}),
}
================================================
FILE: automatic/element/migrations/0001_initial.py
================================================
# Generated by Django 3.0.2 on 2020-01-15 10:02
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('management', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Element',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('descr', models.CharField(max_length=100)),
('locmode', models.CharField(blank=True, choices=[('id', 'id'), ('name', 'name'), ('css selector', 'css selector'), ('xpath', 'xpath'), ('class_name', 'class name'), ('tag_name', 'tag name'), ('link_text', 'link text'), ('portial_link_text', 'portial link text')], max_length=32, null=True)),
('location', models.CharField(blank=True, max_length=200, null=True)),
('createtime', models.DateTimeField(auto_now_add=True)),
('createat', models.CharField(blank=True, max_length=32, null=True)),
('updatetime', models.DateTimeField(auto_now=True)),
('updateat', models.CharField(blank=True, max_length=32, null=True)),
('moduleid', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Module')),
('projectid', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Project')),
],
),
]
================================================
FILE: automatic/element/migrations/__init__.py
================================================
================================================
FILE: automatic/element/models.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-06
"""
from django.db import models
from automatic.management.models import Project, Module
# Create your models here.
class Element(models.Model):
Element_Choice = (
('id','id'),
('name','name'),
('css selector','css selector'),
('xpath','xpath'),
('class name','class name'),
('tag name','tag name'),
('link text','link text'),
('portial link_text','portial link text')
)
projectid = models.ForeignKey(Project, editable=True, on_delete=models.DO_NOTHING)
moduleid = models.ForeignKey(Module, editable=True, on_delete=models.DO_NOTHING)
descr = models.CharField(max_length=100, editable=True)
locmode = models.CharField(max_length=32, choices=Element_Choice, null=True, blank=True, editable=True)
location = models.CharField(max_length=200, null=True, blank=True, editable=True)
createtime = models.DateTimeField(auto_now_add=True)
createat = models.CharField(max_length=32, null=True, blank=True, editable=True)
updatetime = models.DateTimeField(auto_now=True)
updateat = models.CharField(max_length=32, null=True, blank=True, editable=True)
def __unicode__(self):
return self.descr
================================================
FILE: automatic/element/tests.py
================================================
from django.test import TestCase
# Create your tests here.
================================================
FILE: automatic/element/urls.py
================================================
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from automatic.element import views
urlpatterns = [
url(r'list/$', login_required(views.ElementListIndex.as_view()), name='elementlist'),
url(r'add/$', views.add_element, name='elementadd'),
url(r'update/$', views.update_element, name='elementupdate'),
url(r'del/(?P<id>\d+)/$', views.del_element, name='elementdel'),
url(r'get/$', views.get_element, name='getelement'),
url(r'setedit/$', views.set_edit_element, name='seteditelement'),
]
================================================
FILE: automatic/element/views.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-08
"""
import json
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
from automatic.element.forms import *
from django.views.generic import ListView
from automatic.element.models import *
from django.db.models import Q
from django.urls import reverse
from automatic.management.models import Project, UserAndProduct
from automatic.element.models import Element
# Create your views here.
class ElementListIndex(ListView):
context_object_name = 'elementlist'
template_name = 'element/element.html'
paginate_by = 10
elementsum = 0
model = Element
http_method_names = [u'get']
def get_queryset(self):
prodcutid = UserAndProduct.objects.filter(username=self.request.user).values('productname')
elementlist = Element.objects.filter(projectid__in=Project.objects.filter(productid__in=prodcutid).values('id')).order_by('-pk')
prodcutid = self.request.GET.get('check_productname')
projectid = self.request.GET.get('projectid')
moduleid = self.request.GET.get('moduleid')
keyword = self.request.GET.get('keyword')
if prodcutid and int(prodcutid):
elementlist = elementlist.filter(projectid__in=Project.objects.filter(productid=prodcutid).values('id'))
if projectid:
elementlist = elementlist.filter(projectid=projectid)
if moduleid:
elementlist = elementlist.filter(moduleid=moduleid)
if keyword:
elementlist = elementlist.filter(Q(id__icontains=keyword)|Q(location__icontains=keyword)|Q(descr__icontains=keyword))
self.elementsum = len(elementlist)
return elementlist
def get_context_data(self, **kwargs):
context = super(ElementListIndex,self).get_context_data(**kwargs)
namelist = Element.objects.values('descr').annotate()
context['descr'] = namelist
context['elementsum'] = self.elementsum
context['elementform'] = FormElement()
context['userandproduct'] = UserAndProduct.objects.all()
return context
@csrf_exempt
@login_required()
def add_element(request):
if request.method == 'POST':
descr = request.POST['descr']
projectid = request.POST['projectid']
moduleid = request.POST['moduleid']
locmode = request.POST['locmode']
location = request.POST['location']
createat = request.user.username
updateat = request.user.username
mid = Module.objects.get(pk=int(moduleid))
pid = Project.objects.get(pk=int(projectid))
ele = Element(moduleid=mid, projectid=pid, descr=descr, locmode=locmode, location=location, createat=createat, updateat=updateat)
ele.save()
# return HttpResponse(descr + '@' + locmode + '@' + location + '@' + str(mid.pk))
return HttpResponse('添加元素成功。')
else:
return HttpResponse('添加元素失败。')
@csrf_exempt
@login_required()
def update_element(request):
if request.method == 'POST':
post_dict = request.POST
element_dict = {"id":post_dict['elementid'],
"descr": post_dict['eledescr'],
"projectid":post_dict['ele_add_projectid'],
"moduleid": post_dict['moduleid'],
"locmode": post_dict['locmode'],
"location": post_dict['elelocation'],
}
id = element_dict.get('id')
descr = element_dict.get('descr')
projectid = element_dict.get('projectid')
moduleid = element_dict.get('moduleid')
locmode = element_dict.get('locmode')
location = element_dict.get('location')
updateat = request.user.username
updatetime = timezone.now()
e = Element.objects.filter(id=int(id))
e.update(descr=descr, projectid=projectid,moduleid=moduleid,locmode=locmode, location=location,updateat=updateat,updatetime=updatetime)
return HttpResponse('修改成功')
else:
return HttpResponse('修改失败')
@login_required()
def del_element(request, id):
element = get_object_or_404(Element, pk=int(id))
element.delete()
return HttpResponseRedirect(reverse('elementlist'))
@login_required()
def get_element(request):
elementlist = []
projectid = request.GET['projectid']
elelista = Element.objects.raw("select id,(select name from management_module where id= moduleid_id) as modulename,locmode,location,descr from element_element where projectid_id="+projectid)
for i in elelista:
element = {}
element['moduleid'] = i.modulename
element['key'] = i.id
location = i.locmode + "," + i.location
element['location'] = location
element['value'] = "["+str(i.id)+"][" + i.modulename + "]" + i.descr
elementlist.append(element)
return HttpResponse(json.dumps(elementlist))
@login_required()
def set_edit_element(request):
elementid = request.GET['elementid']
element = Element.objects.get(pk=elementid)
elementinfo = {}
elementinfo['id'] = element.pk
elementinfo['descr'] = element.descr
elementinfo['projectid'] = element.projectid.pk
elementinfo['moduleid'] = element.moduleid.pk
elementinfo['locmode'] = element.locmode
elementinfo['location'] = element.location
elementlist = [elementinfo]
return HttpResponse(json.dumps(elementlist))
================================================
FILE: automatic/keywords/__init__.py
================================================
================================================
FILE: automatic/keywords/admin.py
================================================
from django.contrib import admin
# Register your models here.
from automatic.keywords import models
class KeywordAdmin(admin.ModelAdmin):
list_display = (id, 'keyword', 'kwdescr','createat', 'createtime', 'updateat', 'updatetime')
search_fields = ('keyword', 'kwdescr')
admin.site.register(models.Keyword, KeywordAdmin)
================================================
FILE: automatic/keywords/apps.py
================================================
from django.apps import AppConfig
class KeywordsConfig(AppConfig):
name = 'automatic.keywords'
================================================
FILE: automatic/keywords/fixtures/initial_data.json
================================================
[
{
"model": "keywords.keyword",
"pk": 1,
"fields": {
"productid": 0,
"keyword": "click",
"kwdescr": "点击",
"createtime": "2016-09-19T10:17:50Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:17:50Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 2,
"fields": {
"productid": 0,
"keyword": "InputText",
"kwdescr": "输入文本",
"createtime": "2016-09-19T10:18:03Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:18:03Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 3,
"fields": {
"productid": 0,
"keyword": "navigate",
"kwdescr": "页面跳转",
"createtime": "2016-09-19T10:18:47Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:18:47Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 4,
"fields": {
"productid": 0,
"keyword": "sleep",
"kwdescr": "等待[n]秒",
"createtime": "2016-09-19T10:19:14Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:19:14Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 5,
"fields": {
"productid": 0,
"keyword": "switchframe",
"kwdescr": "切换iframe",
"createtime": "2016-09-19T10:19:50Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:19:50Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 6,
"fields": {
"productid": 0,
"keyword": "defaultframe",
"kwdescr": "返回默认Frame",
"createtime": "2016-09-19T10:20:06Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:20:06Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 7,
"fields": {
"productid": 0,
"keyword": "select",
"kwdescr": "下来选择框 input:[value]",
"createtime": "2016-09-28T06:46:58Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:00:03Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 8,
"fields": {
"productid": 0,
"keyword": "selectText",
"kwdescr": "下拉选择框input:[Text]",
"createtime": "2016-11-07T08:59:39Z",
"createat": "tsbc",
"updatetime": "2016-11-07T08:59:39Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 9,
"fields": {
"productid": 0,
"keyword": "uploadfile",
"kwdescr": "上传文件",
"createtime": "2016-10-10T09:06:07Z",
"createat": "tsbc",
"updatetime": "2016-10-10T09:06:07Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 10,
"fields": {
"productid": 0,
"keyword": "moveScroll",
"kwdescr": "移动滚动条到某元素位置",
"createtime": "2016-10-14T10:09:01Z",
"createat": "tsbc",
"updatetime": "2016-10-14T10:09:01Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 11,
"fields": {
"productid": 0,
"keyword": "checkclick",
"kwdescr": "循环勾选一组复选框 [location:父级元素]",
"createtime": "2016-10-18T02:40:57Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:10:59Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 12,
"fields": {
"productid": 0,
"keyword": "refresh",
"kwdescr": "页面刷新",
"createtime": "2017-04-05T10:16:14Z",
"createat": "tsbc",
"updatetime": "2017-04-05T10:16:14Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 13,
"fields": {
"productid": 0,
"keyword": "clicks",
"kwdescr": "点击一组元素中的第n个元素 input:[n]",
"createtime": "2016-11-07T09:02:40Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:02:40Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 14,
"fields": {
"productid": 0,
"keyword": "timestamp",
"kwdescr": "文本框输入当前时间戳",
"createtime": "2016-11-07T09:03:41Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:03:41Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 15,
"fields": {
"productid": 0,
"keyword": "submit",
"kwdescr": "表单提交",
"createtime": "2016-11-07T09:06:07Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:06:07Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 16,
"fields": {
"productid": 0,
"keyword": "jscript",
"kwdescr": "执行javascript脚本",
"createtime": "2016-10-14T09:36:26Z",
"createat": "tsbc",
"updatetime": "2016-10-14T09:36:26Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 18,
"fields": {
"productid": 0,
"keyword": "closeBrowser",
"kwdescr": "关闭浏览器",
"createtime": "2016-11-07T09:05:36Z",
"createat": "tsbc",
"updatetime": "2016-11-07T09:05:36Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 19,
"fields": {
"productid": 0,
"keyword": "assert",
"kwdescr": "通用断言",
"createtime": "2016-09-19T10:18:25Z",
"createat": "tsbc",
"updatetime": "2016-09-19T10:18:25Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 20,
"fields": {
"productid": 0,
"keyword": "assertTrue",
"kwdescr": "验证元素存在",
"createtime": "2016-09-19T10:20:17Z",
"createat": "tsbc",
"updatetime": "2016-10-13T09:57:37Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 21,
"fields": {
"productid": 0,
"keyword": "assertFalse",
"kwdescr": "验证元素不存在",
"createtime": "2016-10-13T09:50:05Z",
"createat": "tsbc",
"updatetime": "2016-10-13T09:50:05Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 22,
"fields": {
"productid": 0,
"keyword": "assertUrl",
"kwdescr": "验证当前页面Url地址[input:期望值]",
"createtime": "2016-10-08T03:26:42Z",
"createat": "tsbc",
"updatetime": "2016-10-08T03:26:42Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 23,
"fields": {
"productid": 0,
"keyword": "isEnabled",
"kwdescr": "验证元素是否置灰",
"createtime": "2016-11-09T06:06:29Z",
"createat": "wenjuan.wang",
"updatetime": "2016-11-09T06:06:29Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 24,
"fields": {
"productid": 0,
"keyword": "Notassert",
"kwdescr": "通用断言【反向】",
"createtime": "2016-12-07T07:55:49Z",
"createat": "tsbc",
"updatetime": "2016-12-07T07:55:49Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 25,
"fields": {
"productid": 0,
"keyword": "untilshow",
"kwdescr": "等待页面加载直到发现当前元素",
"createtime": "2017-05-17T08:37:16Z",
"createat": "tsbc",
"updatetime": "2017-05-17T08:52:30Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 26,
"fields": {
"productid": 0,
"keyword": "exists_file",
"kwdescr": "验证data目录中某个文件是否存在",
"createtime": "2017-05-25T02:57:09Z",
"createat": "tsbc",
"updatetime": "2017-05-25T02:57:09Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 27,
"fields": {
"productid": 0,
"keyword": "udpsend",
"kwdescr": "udp协议发送syslog日志|使用参数看工具syslog",
"createtime": "2017-05-31T03:27:29Z",
"createat": "tsbc",
"updatetime": "2017-05-31T03:27:29Z",
"updateat": "tsbc"
}
},
{
"model": "keywords.keyword",
"pk": 28,
"fields": {
"productid": 0,
"keyword": "ssh",
"kwdescr": "ssh访问设备执行命令[host,port,user,pass,cmd]",
"createtime": "2016-10-10T12:02:18Z",
"createat": "tsbc",
"updatetime": "2016-10-10T12:02:18Z",
"updateat": "tsbc"
}
}
]
================================================
FILE: automatic/keywords/migrations/0001_initial.py
================================================
# Generated by Django 3.0.2 on 2020-01-15 10:02
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Keyword',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('productid', models.IntegerField(blank=True, null=True, verbose_name='所属产品')),
('keyword', models.CharField(max_length=32, unique=True)),
('kwdescr', models.TextField(blank=True, null=True)),
('createtime', models.DateTimeField(auto_now_add=True)),
('createat', models.CharField(blank=True, max_length=32, null=True)),
('updatetime', models.DateTimeField(auto_now=True)),
('updateat', models.CharField(blank=True, max_length=32, null=True)),
],
options={
'ordering': ['productid'],
},
),
]
================================================
FILE: automatic/keywords/migrations/__init__.py
================================================
================================================
FILE: automatic/keywords/models.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-06
"""
from django.db import models
# Create your models here.
class Keyword(models.Model):
productid = models.IntegerField(verbose_name='所属产品', null=True, blank=True, editable=True)
keyword = models.CharField(max_length=32, unique=True)
kwdescr = models.TextField(null=True,blank=True,editable=True)
createtime = models.DateTimeField(auto_now_add=True)
createat = models.CharField(max_length=32, null=True, blank=True, editable=True)
updatetime = models.DateTimeField(auto_now=True)
updateat = models.CharField(max_length=32, null=True, blank=True, editable=True)
def __unicode__(self):
return self.keyword
class Meta:
ordering = ["productid"]
================================================
FILE: automatic/keywords/tests.py
================================================
from django.test import TestCase
# Create your tests here.
================================================
FILE: automatic/keywords/urls.py
================================================
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from automatic.keywords import views
urlpatterns = [
url(r'list/$', login_required(views.KeyWordListIndex.as_view()), name='keywordlist'),
url(r'add/$', views.add_keyword, name='keywordadd'),
url(r'update/$', views.update_keyword, name='keywordupdate'),
url(r'del/(?P<id>\d+)/$', views.del_keyword, name='keyworddel'),
url(r'get/$', views.get_keyword, name='getkeyword'),
url(r'setedit/$', views.set_edit_keyword, name='seteditelement'),
]
================================================
FILE: automatic/keywords/views.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-08
"""
import json
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
from automatic.element.forms import *
from django.views.generic import ListView
from automatic.element.models import *
from django.db.models import Q
from django.urls import reverse
from automatic.management.models import Product, Project, UserAndProduct
from automatic.keywords.models import Keyword
class KeyWordListIndex(ListView):
context_object_name = 'keywordlist'
template_name = 'keywords/keyword.html'
paginate_by = 10
keywordsum = 0
model = Keyword
http_method_names = [u'get']
def get_queryset(self):
keywordlist = Keyword.objects.all().order_by('-pk')
keyword = self.request.GET.get('keyword')
if keyword:
keywordlist = keywordlist.filter(Q(keyword__icontains=keyword)|Q(kwdescr__icontains=keyword))
self.keywordsum = len(keywordlist)
return keywordlist
def get_context_data(self, **kwargs):
context = super(KeyWordListIndex,self).get_context_data(**kwargs)
context['userandproduct'] = UserAndProduct.objects.all()
context['productlist'] = Product.objects.all()
context['keywordsum'] = self.keywordsum
return context
@login_required()
def add_keyword(request):
if request.method == 'POST':
name = request.POST['keyword']
descr = request.POST['kwdescr']
productid = request.POST['productid']
createat = request.user.username
updateat = request.user.username
keyword = Keyword(productid=productid, keyword=name, kwdescr=descr, createat=createat, updateat=updateat)
try:
keyword.save()
except Exception as e:
return HttpResponse(e)
return HttpResponse('添加关键字成功。')
else:
return HttpResponse('添加关键字失败。')
@csrf_exempt
@login_required()
def update_keyword(request):
if request.method == 'POST':
id = request.POST['keywordid']
name = request.POST['keyword']
descr = request.POST['kwdescr']
productid = request.POST['productname']
updateat = request.user.username
updatetime = timezone.now()
k = Keyword.objects.filter(id=int(id))
k.update(productid=productid, keyword=name, kwdescr=descr, updateat=updateat, updatetime=updatetime)
return HttpResponse('修改关键字成功。')
else:
return HttpResponse('修改关键字失败。')
@login_required()
def del_keyword(request, id):
keyword = get_object_or_404(Keyword, pk=int(id))
keyword.delete()
return HttpResponseRedirect(reverse('keywordlist'))
@login_required()
def get_keyword(request):
keywordlist = []
productid = request.GET['productid']
kwlist = Keyword.objects.filter(Q(productid=productid)|Q(productid=0))
for i in kwlist:
keywordinfo = {}
keywordinfo['key'] = i.id
keywordinfo['kwdescr'] = i.kwdescr
keywordinfo['keyword'] = i.keyword
keywordinfo['productid'] = i.productid
keywordlist.append(keywordinfo)
return HttpResponse(json.dumps(keywordlist))
@login_required()
def set_edit_keyword(request):
keywordid = request.GET['keywordid']
kw = Keyword.objects.get(pk=keywordid)
keywordinfo = {}
keywordinfo['id'] = kw.pk
keywordinfo['descr'] = kw.kwdescr
keywordinfo['name'] = kw.keyword
keywordinfo['productid'] = kw.productid
keywordlist = [keywordinfo]
return HttpResponse(json.dumps(keywordlist))
================================================
FILE: automatic/management/__init__.py
================================================
================================================
FILE: automatic/management/admin.py
================================================
from django.contrib import admin
# Register your models here.
from automatic.management import models
class ProductAdmin(admin.ModelAdmin):
list_display = (id, 'name', 'isenabled', 'descr','createat', 'createtime', 'updateat', 'updatetime')
search_fields = ('name','descr')
class ProjectAdmin(admin.ModelAdmin):
list_display = (id, 'name', 'isenabled','version','descr','createat', 'createtime', 'updateat', 'updatetime')
search_fields = ('name','descr','version')
class ModuleAdmin(admin.ModelAdmin):
list_display = (id, 'name', 'isenabled', 'createat', 'createtime', 'updateat', 'updatetime')
search_fields = ('name',)
admin.site.register(models.Product, ProductAdmin)
admin.site.register(models.Project, ProjectAdmin)
admin.site.register(models.Module, ModuleAdmin)
================================================
FILE: automatic/management/apps.py
================================================
from django.apps import AppConfig
class ManagementConfig(AppConfig):
name = 'automatic.management'
================================================
FILE: automatic/management/migrations/0001_initial.py
================================================
# Generated by Django 3.0.2 on 2020-01-15 10:02
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Product',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True, verbose_name='产品名称')),
('isenabled', models.BooleanField(blank=True, default=True, verbose_name='产品状态')),
('descr', models.TextField(blank=True, null=True, verbose_name='产品描述')),
('createtime', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
('updatetime', models.DateTimeField(auto_now=True, null=True, verbose_name='更新时间')),
('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
],
options={
'ordering': ['-sortby'],
},
),
migrations.CreateModel(
name='UserAndProduct',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('productname', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Product')),
('username', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Project',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True, verbose_name='项目名称')),
('version', models.CharField(blank=True, max_length=32, null=True, verbose_name='版本')),
('isenabled', models.BooleanField(default=True, verbose_name='状态')),
('descr', models.TextField(blank=True, null=True, verbose_name='项目描述')),
('createtime', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
('updatetime', models.DateTimeField(auto_now=True, null=True, verbose_name='更新时间')),
('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
('productid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='management.Product', verbose_name='产品名称')),
],
options={
'ordering': ['-sortby'],
},
),
migrations.CreateModel(
name='Module',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, verbose_name='模块名称')),
('isenabled', models.BooleanField(default=True, verbose_name='状态')),
('createtime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
('updatetime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
('projectid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='management.Project', verbose_name='所属项目')),
],
options={
'ordering': ['-sortby'],
},
),
]
================================================
FILE: automatic/management/migrations/__init__.py
================================================
================================================
FILE: automatic/management/models.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-06
"""
from __future__ import unicode_literals
import datetime
from django.db import models
from auto_auth.models import User
# Create your models here.
class Product(models.Model):
name = models.CharField(max_length=32, verbose_name='产品名称', unique=True)
# version = models.CharField(max_length=32)
isenabled = models.BooleanField(default=True, blank=True, verbose_name='产品状态')
descr = models.TextField(null=True, blank=True, verbose_name='产品描述')
createtime = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name='创建时间')
createat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='创建者')
updatetime = models.DateTimeField(auto_now=True,null=True, blank=True, verbose_name='更新时间')
updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
if not self.id:
self.createtime = datetime.datetime.now()
self.updatetime = datetime.datetime.now()
super(Product, self).save(*args, **kwargs)
class Meta:
ordering = ["-sortby"]
class Project(models.Model):
productid = models.ForeignKey(Product, verbose_name='产品名称', on_delete=models.CASCADE)
name = models.CharField(max_length=32, unique=True, verbose_name='项目名称')
version = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='版本')
isenabled = models.BooleanField(default=True, verbose_name='状态')
descr = models.TextField(null=True, blank=True, editable=True,verbose_name='项目描述')
createtime = models.DateTimeField(auto_now_add=True, null=True, blank=True, editable=True,verbose_name='创建时间')
createat = models.CharField( max_length=32, null=True, blank=True, editable=True, verbose_name='创建者')
updatetime = models.DateTimeField(auto_now=True,null=True, blank=True, verbose_name='更新时间')
updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
def __unicode__(self):
return self.name
class Meta:
ordering = ["-sortby"]
class Module(models.Model):
projectid = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.CASCADE)
name = models.CharField(max_length=32, verbose_name='模块名称')
isenabled = models.BooleanField(default=True, verbose_name='状态')
createtime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
createat = models.CharField(max_length=32 ,null=True, blank=True, editable=True, verbose_name='创建者')
updatetime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
def __unicode__(self):
return self.name
class Meta:
ordering = ["-sortby"]
class UserAndProduct(models.Model):
username = models.ForeignKey(User, on_delete=models.DO_NOTHING)
productname = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
================================================
FILE: automatic/management/tests.py
================================================
from django.test import TestCase
# Create your tests here.
================================================
FILE: automatic/management/urls.py
================================================
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from automatic.management import views
urlpatterns = [
url(r'^product/add/$', views.add_product, name='productadd'),
url(r'^product/view/(?P<id>\d+)', views.view_product, name='productview'),
url(r'^product/list/$', login_required(views.ProductListIndex.as_view()), name='productlist'),
url(r'^product/update/$', views.update_product, name='productupdate'),
url(r'^product/del/(?P<id>\d+)/$', views.del_product, name='productdel'),
url(r'^project/add/$', views.add_project, name='projectadd'),
url(r'^project/list/$', login_required(views.ProjectListIndex.as_view()), name='projectlist'),
url(r'^project/view/(?P<id>\d+)', views.view_project, name='projectview'),
url(r'^project/update/$', views.update_project, name='projectupdate'),
url(r'^project/del/(?P<id>\d+)/$', views.del_project, name='projectdel'),
url(r'^module/add/$', views.add_module, name='moduleadd'),
# url(r'^module/list/$', login_required(views.ModuleListIndex.as_view()), name='modulelist'),
url(r'^module/update/$', views.update_module, name='moduleupdate'),
url(r'^module/del/(?P<id>\d+)/$', views.del_module, name='moduledel'),
url(r'^get/project/$', views.get_project, name='getproject'),
url(r'^get/module/$', views.get_module, name='getmodule'),
url(r'^get/connecteduser/$', views.get_connected_user, name='getconnecteduser'),
url(r'^product/user/$', views.product_user, name='productuser'),
url(r'^get/moduleList/$', views.get_module_list, name='getmodulelist'),
url(r'^setedit/product/$', views.set_edit_product, name='seteditproduct'),
url(r'^setedit/project/$', views.set_edit_project, name='seteditproject'),
url(r'^setedit/module/$', views.set_edit_module, name='seteditmodule'),
url(r'^syslog/home/$', views.page_syslog, name='toolsyslog'),
url(r'^snmp/home/$', views.comingsoon, name='toolsnmp'),
]
================================================
FILE: automatic/management/views.py
================================================
# -*- coding:utf-8 -*-
"""
__author__ = 'Ray'
mail:tsbc@vip.qq.com
2020-01-06
"""
import logging,json
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import ListView
from django.db.models import Q
from django.urls import reverse
from automatic.management.models import Product, Project, Module, User, UserAndProduct
from automatic.testcase.models import Case
# Create your views here.
@login_required()
def add_product(request):
if request.method == 'POST':
post_dict = request.POST
product_dict = {"name": post_dict['productname'],
"descr": post_dict['descr'],
"sortby":post_dict['sortby'],
# "isenabled": post_dict['isenabled'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
name = product_dict.get('name')
isenabled = isenabled
descr = product_dict.get('descr')
sortby = product_dict.get('sortby')
createat = request.user.username
updateat = request.user.username
product = Product(name=name, isenabled=isenabled,descr=descr,sortby=sortby, createat=createat, updateat=updateat)
product.save()
return HttpResponse('创建成功')
else:
return HttpResponse('创建失败')
@csrf_exempt
@login_required()
def update_product(request):
if request.method == 'POST':
post_dict = request.POST
product_dict = {"id":post_dict['productid'],
"name": post_dict['productname'],
"descr": post_dict['descr'],
"sortby":post_dict['sortby'],
# "isenabled": post_dict['isenabled'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
id = product_dict.get('id')
name = product_dict.get('name')
isenabled = isenabled
descr = product_dict.get('descr')
sortby = product_dict.get('sortby')
updateat = request.user.username
updatetime = timezone.now()
p = Product.objects.filter(id=int(id))
p.update(name=name, isenabled=isenabled,descr=descr,sortby=sortby, updateat=updateat, updatetime=updatetime)
return HttpResponse('修改成功')
else:
return HttpResponse('修改失败')
@login_required()
def del_product(request,id):
product = get_object_or_404(Product,pk=int(id))
product.delete()
return HttpResponseRedirect(reverse('productlist'))
@csrf_exempt
@login_required()
def view_product(request, id):
product = get_object_or_404(Product, pk=int(id))
errors = []
if int(id):
product = Product.objects.get(pk=int(id))
projectlist = product.project_set.all()
return render(request, 'management/productview.html', {'product':product,'projectlist':projectlist})
else:
errors.append('Error!!!')
return render(request, 'management/productlist.html', {'errors', errors})
#
# def productlist(request):
# productlist = Product.objects.all()
# return render_to_response('productlist.html', {'productlist': productlist})
class ProductListIndex(ListView):
context_object_name = 'productlist'
template_name = 'management/productlist.html'
paginate_by = 10
productsum = 0
model = Product
http_method_names = [u'get',]
def get_queryset(self):
productlist = Product.objects.all().order_by('-sortby')
productname = self.request.GET.get('productname')
keyword = self.request.GET.get('keyword')
if productname:
productlist = productlist.filter(name=productname)
if keyword:
productlist = productlist.filter(Q(name__icontains=keyword)|Q(descr__icontains=keyword))
self.productsum = len(productlist)
return productlist
def get_context_data(self, **kwargs):
context = super(ProductListIndex,self).get_context_data(**kwargs)
namelist = Product.objects.values('name').annotate()
context['name'] = namelist
context['productsum'] = self.productsum
return context
class ProjectListIndex(ListView):
context_object_name = 'projectlist'
template_name = 'management/projectlist.html'
paginate_by = 10
projectsum = 0
model = Project
http_method_names = [u'get',]
def get_queryset(self):
projectlist = Project.objects.all().order_by('-sortby')
productid = self.request.GET.get('productid')
projectid = self.request.GET.get('projectid')
keyword = self.request.GET.get('keyword')
if productid:
projectlist = projectlist.filter(productid=productid)
if projectid:
projectlist = projectlist.filter(id=projectid)
if keyword:
projectlist = projectlist.filter(Q(name__icontains=keyword)|Q(descr__icontains=keyword))
self.projectsum = len(projectlist)
return projectlist
def get_context_data(self, **kwargs):
context = super(ProjectListIndex,self).get_context_data(**kwargs)
namelist = Project.objects.values('name').annotate()
context['name'] = namelist
context['productlist'] = Product.objects.all().order_by('-sortby')
context['productsum'] = self.projectsum
return context
@csrf_exempt
@login_required()
def add_project(request):
if request.method == 'POST':
post_dict = request.POST
project_dict = {"productid":post_dict['productid'],
"name": post_dict['projectname'],
"descr": post_dict['descr'],
"sortby":post_dict['sortby'],
"version": post_dict['version'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
productid = project_dict.get('productid')
name = project_dict.get('name')
isenabled = isenabled
descr = project_dict.get('descr')
version = project_dict.get('version')
sortby = project_dict.get('sortby')
createat = request.user.username
updateat = request.user.username
project = Project(productid=Product.objects.get(pk=productid), name=name, isenabled=isenabled, version=version, descr=descr,sortby=sortby,
createat=createat, updateat=updateat)
project.save()
return HttpResponse('创建成功')
else:
return HttpResponse('创建失败')
@csrf_exempt
@login_required()
def update_project(request):
if request.method == 'POST':
post_dict = request.POST
project_dict = {"id":post_dict['projectid'],
"name": post_dict['projectname'],
"descr": post_dict['descr'],
"version":post_dict['version'],
"sortby":post_dict['sortby'],
# "isenabled": post_dict['isenabled'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
id = project_dict.get('id')
name = project_dict.get('name')
isenabled = isenabled
descr = project_dict.get('descr')
version = project_dict.get('version')
sortby = project_dict.get('sortby')
updateat = request.user.username
updatetime = timezone.now()
p = Project.objects.filter(id=int(id))
p.update(name=name, isenabled=isenabled,descr=descr, version=version ,sortby=sortby, updateat=updateat, updatetime=updatetime)
return HttpResponse('修改成功')
else:
return HttpResponse('修改失败')
@login_required()
def del_project(request,id):
project = get_object_or_404(Project,pk=int(id))
x = project.productid
project.delete()
return HttpResponseRedirect('/setting/product/view/' + str(Product.objects.get(name=x).id))
@csrf_exempt
@login_required()
def view_project(request, id):
project = get_object_or_404(Project, pk=int(id))
errors = []
if int(id):
product = project.productid
modulelist = project.module_set.all().order_by('-sortby')
return render(request, 'management/projectview.html', {'project':project,'product':product,'modulelist':modulelist})
else:
errors.append('Error!!!')
return render(request, 'management/projectview.html', {'errors', errors})
class ModuleListIndex(ListView):
context_object_name = 'modulelist'
template_name = 'management/modulelist.html'
paginate_by = 10
model = Module
modulesum = 0
http_method_names = [u'get']
def get_queryset(self):
modulelist = Module.objects.all().order_by('-sortby')
projectid = self.request.GET.get('projectid')
modulename = self.request.GET.get('modulename')
keyword = self.request.GET.get('keyword')
if projectid:
modulelist = modulelist.filter(projectid=Project.objects.get(name=projectid).id)
if modulename:
modulelist = modulelist.filter(name=modulename)
if keyword:
modulelist = modulelist.filter(Q(name__icontains=keyword)|Q(descr__icontains=keyword))
self.modulesum = len(modulelist)
return modulelist
def get_context_data(self, **kwargs):
context = super(ModuleListIndex,self).get_context_data(**kwargs)
namelist = Module.objects.values('name').annotate()
context['name'] = namelist
context['modulesum'] = self.modulesum
return context
@csrf_exempt
@login_required()
def add_module(request):
if request.method == 'POST':
post_dict = request.POST
project_dict = {"projectid":post_dict['projectid'],
"name": post_dict['modulename'],
"sortby":post_dict['sortby'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
projectid = project_dict.get('projectid')
name = project_dict.get('name')
isenabled = isenabled
sortby = project_dict.get('sortby')
createat = request.user.username
updateat = request.user.username
module = Module(projectid=Project.objects.get(pk=projectid), name=name, isenabled=isenabled, sortby=sortby,
createat=createat, updateat=updateat)
module.save()
return HttpResponse('创建成功')
else:
return HttpResponse('创建失败')
@csrf_exempt
@login_required()
def update_module(request):
if request.method == 'POST':
post_dict = request.POST
module_dict = {"id":post_dict['moduleid'],
"name": post_dict['modulename'],
"sortby":post_dict['sortby'],
# "isenabled": post_dict['isenabled'],
}
if 'isenabled' in post_dict:
isenabled = True
else:
isenabled = False
id = module_dict.get('id')
name = module_dict.get('name')
isenabled = isenabled
sortby = module_dict.get('sortby')
updateat = request.user.username
updatetime = timezone.now()
m = Module.objects.filter(id=int(id))
m.update(name=name, isenabled=isenabled,sortby=sortby, updateat=updateat, updatetime=updatetime)
return HttpResponse('修改成功')
else:
return HttpResponse('修改失败')
@login_required()
def del_module(request, id):
module = get_object_or_404(Module,pk=int(id))
module.delete()
return HttpResponseRedirect('/setting/project/view/'+str(module.projectid_id))
@login_required()
def get_project(request):
projectlist = []
productid = request.GET['productid']
pjlist = Project.objects.filter(productid=productid)
for i in pjlist:
project = {}
project['key'] = i.id
project['value'] = i.name
projectlist.append(project)
return HttpResponse(json.dumps(projectlist))
@login_required()
def get_module(request):
modulelist = []
projectid = request.GET['projectid']
if projectid == u'':
return HttpResponse(u'[]')
modlist = Module.objects.filter(projectid=projectid, isenabled=True)
for i in modlist:
module = {}
module['key'] = i.id
module['value'] = i.name
modulelist.append(module)
return HttpResponse(json.dumps(modulelist))
@login_required()
def get_connected_user(request):
connecteduserlist=[]
productid = request.GET['productid']
#product = Product.objects.filter(pk=productid)[0].name
userandproduct = UserAndProduct.objects.filter(productname=productid)
useridlist=userandproduct.values('username')
for i in useridlist:
user={}
user['key'] = User.objects.get(pk=i['username']).pk
user['username'] = User.objects.get(pk=i['username']).username
user['realname'] = User.objects.get(pk=i['username']).realname
connecteduserlist.append(user)
return HttpResponse(json.dumps(connecteduserlist))
@login_required()
def get_module_list(request):
post_dict = request.GET
caselist = []
projectid = post_dict['projectid']
if post_dict['issmoke'] == '1':
issmoke = True
else:
issmoke = False
if projectid == u'':
return HttpResponse(u'[]')
if issmoke:
cases = Case.objects.filter(projectid=projectid, issmoke=issmoke, isenabled=True).order_by("moduleid_id", "id")
else:
cases = Case.objects.filter(projectid=projectid, isenabled=True).order_by("moduleid_id", "id")
moduleid = -1
for case in cases:
if moduleid != case.moduleid_id:
moduleid = case.moduleid_id
caselist.append(u'{id:9999999%s, pId:99999990, name:"%s"}' % (case.moduleid_id, case.moduleid.name))
caselist.append(u'{id:%s, pId:9999999%s, name:"%s、%s"}' % (case.id, case.moduleid_id, case.id, case.casedesc))
if caselist:
caselist.insert(0, u'{id:99999990, pId:0, name:"%s", open:true}' % (case.projectid.name))
caseData = u'[%s]' % u','.join(caselist)
return HttpResponse(caseData)
@login_required()
def set_edit_product(request):
productid = request.GET['productid']
product = Product.objects.get(pk=productid)
pd = {}
pd['id'] = product.pk
pd['name'] = product.name
pd['descr'] = product.descr
pd['isenabled'] = product.isenabled
pd['sortby'] = product.sortby
productlist = [pd]
return HttpResponse(json.dumps(productlist))
@login_required()
def set_edit_project(request):
projectid = request.GET['projectid']
project = Project.objects.get(pk=projectid)
pj = {}
pj['id'] = project.pk
pj['name'] = project.name
pj['descr'] = project.descr
pj['isenabled'] = project.isenabled
pj['version'] = project.version
pj['sortby'] = project.sortby
projectlist = [pj]
return HttpResponse(json.dumps(projectlist))
@login_required()
def set_edit_module(request):
moduleid = request.GET['moduleid']
module = Module.objects.get(pk=moduleid)
md = {}
md['id'] = module.pk
md['name'] = module.name
md['isenabled'] = module.isenabled
md['sortby'] = module.sortby
modulelist = [md]
return HttpResponse(json.dumps(modulelist))
@csrf_exempt
@login_required()
def product_user(request):
if request.method == 'POST':
post_dict = request.POST
username = post_dict.getlist('realname')
productname = post_dict['product']
UserAndProduct.objects.filter(productname=productname).delete()
for i in range(0, len(username)):
userandproduct = UserAndProduct(username=User.objects.get(pk=username[i]),productname=Product.objects.get(pk=productname))
userandproduct.save()
return HttpResponse('授权成功')
else:
return HttpResponse('授权失败')
def page_syslog(request):
return render(request, 'management/syslog.html')
def comingsoon(request):
return render(request, 'comingsoon.html')
================================================
FILE: automatic/settings/__init__.py
================================================
================================================
FILE: automatic/settings/common.py
================================================
"""
Django settings for automatic project.
Generated by 'django-admin startproject' using Django 3.0.2.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..').replace('\\', '/'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '$%rn58oxcu-y8$gn!8+y&&92klv0a5hdwa1v-mn5tezm$w+7x4'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'auto_auth',
'automatic.management',
'automatic.element',
'automatic.keywords',
'automatic.testcase',
'automatic.testtask',
'automatic.webinterface',
]
AUTH_USER_MODEL = "auto_auth.User"
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'automatic.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'automatic.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
MYSQL_USERNAME = os.environ.get('MYSQL_USERNAME', 'root')
MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', '123456')
MYSQL_HOST = os.environ.get('MYSQL_HOST', 'localhost')
MYSQL_PORT = os.environ.get('MYSQL_PORT', '3306')
MYSQL_DBNAME = os.environ.get('MYSQL_DBNAME', 'automatic')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': MYSQL_DBNAME,
'USER': MYSQL_USERNAME,
'PASSWORD': MYSQL_PASSWORD,
'HOST': MYSQL_HOST,
'PORT': MYSQL_PORT,
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
#RabbitMq
RABBITMQ_STATUS = False
RABBITMQ_CONFIG = {'AMQP_URI': "amqp://guest:guest@192.168.72.127:31141"}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
# LANGUAGE_CODE = 'en-us'
# LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(ROOT_PATH, 'static').replace('\\', '/'),
]
LOGIN_REDIRECT_URL = '/index/'
LOGIN_URL = '/account/login/'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(ROOT_PATH, 'templates/').replace('\\', '/'),
],
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.static',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
],
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]
},
},
]
================================================
FILE: automatic/signals.py
================================================
from django.dispatch import Signal
USER_REGISTERED_SIGNAL = Signal(providing_args=['user'])
================================================
FILE: automatic/static/css/ak-base-style.css
================================================
@charset "utf-8";
body { font-size:12px; font-family:Arial,'Microsoft Yahei'; color:#555;}
.ak-clear { clear:both;}
.ak-left { float:left;}
.ak-right { float:right;}
.ak-ellipsis { overflow:hidden; white-space:nowrap !important;text-overflow:ellipsis;}
.ak-font-normal { font-size:12px; font-family: Arial,'Microsoft Yahei'; color:#555;}
.ak-clearfix { zoom:1;}
.ak-clearfix:after { content:"."; overflow:hidden; clear:both; visibility:hidden; display:block; height:0;}
/*a*/
a { color: #555; text-decoration: none;}
a,a:focus,
a:hover,
a:active,
button,
button:hover {
outline: 0 !important;
}
a:hover,a:focus { text-decoration: none;}
a:hover { color: #327de4;}
/*Images*/
img.img-circle{ border-radius: 50% !important; }
img.img-w40 { width: 40px;height: 40px;}
img.img-w50 { width: 50px; height: 50px;}
img.img-w60 { width: 60px; height: 60px;}
img.img-100 { width: 100px; height: 100px;}
img.img-center,.img-center img { margin-left: auto; margin-right: auto;}
img.btn-img {width: 120px; height: 45px;}
pre.pre-high {width:100%; height: 330px; margin: 0 auto; text-align: left;}
.main-mid {width:50%;margin: 0 auto; text-align: left;}
/*radius*/
.no-radius {border-radius:0!important;}
/*Full Width*/
.full-width { width: 100%;}
/*margin*/
.no-margin { margin: 0px!important;}
.m-0 { margin:0px!important;}
.m-5 { margin:5px!important;}
.m-10 { margin:10px!important;}
.m-15 { margin:15px!important;}
.m-20 { margin:20px!important;}
.m-25 { margin:25px!important;}
.m-30 { margin:30px!important;}
.m-35 { margin:35px!important;}
.m-40 { margin:40px!important;}
.m-45 { margin:45px!important;}
.m-50 { margin:50px!important;}
.m-100 { margin:100px!important;}
.m-lr-0 { margin-left:0px!important; margin-right:0px!important;}
.m-lr-5 { margin-left:5px!important; margin-right:5px!important;}
.m-lr-10 { margin-left:10px!important; margin-right:10px!important;}
.m-lr-15 { margin-left:15px!important; margin-right:15px!important;}
.m-lr-20 { margin-left:20px!important; margin-right:20px!important;}
.m-lr-25 { margin-left:25px!important; margin-right:25px!important;}
.m-lr-30 { margin-left:30px!important; margin-right:30px!important;}
.m-lr-35 { margin-left:35px!important; margin-right:35px!important;}
.m-lr-40 { margin-left:40px!important; margin-right:40px!important;}
.m-lr-45 { margin-left:45px!important; margin-right:45px!important;}
.m-lr-50 { margin-left:50px!important; margin-right:50px!important;}
.m-lr-100 { margin-left:100px!important; margin-right:100px!important;}
.m-tb-0 { margin-top:0px!important; margin-bottom:0px!important;}
.m-tb-5 { margin-top:5px!important; margin-bottom:5px!important;}
.m-tb-10 { margin-top:10px!important; margin-bottom:10px!important;}
.m-tb-15 { margin-top:15px!important; margin-bottom:15px!important;}
.m-tb-20 { margin-top:20px!important; margin-bottom:20px!important;}
/*.m-tb-25 { margin-top:25px!important; margin-bottom:25!important;}*/
.m-tb-30 { margin-top:30px!important; margin-bottom:30px!important;}
.m-tb-35 { margin-top:35px!important; margin-bottom:35px!important;}
.m-tb-40 { margin-top:40px!important; margin-bottom:40px!important;}
.m-tb-45 { margin-top:45px!important; margin-bottom:45px!important;}
.m-tb-50 { margin-top:50px!important; margin-bottom:50px!important;}
.m-tb-100 { margin-top:100px!important; margin-bottom:100px!important;}
.m-t-0 { margin-top:0px!important;}
.m-t-5 { margin-top:5px!important;}
.m-t-10 { margin-top:10px!important;}
.m-t-15 { margin-top:15px!important;}
.m-t-20 { margin-top:20px!important;}
.m-t-25 { margin-top:25px!important;}
.m-t-30 { margin-top:30px!important;}
.m-t-35 { margin-top:35px!important;}
.m-t-40 { margin-top:40px!important;}
.m-t-45 { margin-top:45px!important;}
.m-t-50 { margin-top:50px!important;}
.m-t-100 { margin-top:100px!important;}
.m-r-0 { margin-right:0px!important;}
.m-r-5 { margin-right:5px!important;}
.m-r-10 { margin-right:10px!important;}
.m-r-15 { margin-right:15px!important;}
.m-r-20 { margin-right:20px!important;}
.m-r-25 { margin-right:25px!important;}
.m-r-30 { margin-right:30px!important;}
.m-r-35 { margin-right:35px!important;}
.m-r-40 { margin-right:40px!important;}
.m-r-45 { margin-right:45px!important;}
.m-r-50 { margin-right:50px!important;}
.m-r-100 { margin-right:100px!important;}
.m-b-0 { margin-bottom:0px!important;}
.m-b-5 { margin-bottom:5px!important;}
.m-b-10 { margin-bottom:10px!important;}
.m-b-15 { margin-bottom:15px!important;}
.m-b-20 { margin-bottom:20px!important;}
.m-b-25 { margin-bottom:25px!important;}
.m-b-30 { margin-bottom:30px!important;}
.m-b-35 { margin-bottom:35px!important;}
.m-b-40 { margin-bottom:40px!important;}
.m-b-45 { margin-bottom:45px!important;}
.m-b-50 { margin-bottom:50px!important;}
.m-b-100 { margin-bottom:100px!important;}
.m-l-0 { margin-left:0px!important;}
.m-l-5 { margin-left:5px!important;}
.m-l-10 { margin-left:10px!important;}
.m-l-15 { margin-left:15px!important;}
.m-l-20 { margin-left:20px!important;}
.m-l-25 { margin-left:25px!important;}
.m-l-30 { margin-left:30px!important;}
.m-l-35 { margin-left:35px!important;}
.m-l-40 { margin-left:40px!important;}
.m-l-45 { margin-left:45px!important;}
.m-l-50 { margin-left:50px!important;}
.m-l-100 { margin-left:100px!important;}
/*padding*/
.no-padding { padding: 0px!important;}
.p-0 { padding:0px!important;}
.p-5 { padding:5px!important;}
.p-10 { padding:10px!important;}
.p-15 { padding:15px!important;}
.p-20 { padding:20px!important;}
.p-25 { padding:25px!important;}
.p-30 { padding:30px!important;}
.p-35 { padding:35px!important;}
.p-40 { padding:40px!important;}
.p-45 { padding:45px!important;}
.p-50 { padding:50px!important;}
.p-100 { padding:100px!important;}
.p-lr-0 { padding-left:0px!important; padding-right:0px!important;}
.p-lr-5 { padding-left:5px!important; padding-right:5px!important;}
.p-lr-10 { padding-left:10px!important; padding-right:10px!important;}
.p-lr-15 { padding-left:15px!important; padding-right:15px!important;}
.p-lr-20 { padding-left:20px!important; padding-right:20px!important;}
.p-lr-25 { padding-left:25px!important; padding-right:25px!important;}
.p-lr-30 { padding-left:30px!important; padding-right:30px!important;}
.p-lr-35 { padding-left:35px!important; padding-right:35px!important;}
.p-lr-40 { padding-left:40px!important; padding-right:40px!important;}
.p-lr-45 { padding-left:45px!important; padding-right:45px!important;}
.p-lr-50 { padding-left:50px!important; padding-right:50px!important;}
.p-lr-100 { padding-left:100px!important; padding-right:100px!important;}
.p-tb-0 { padding-top:0px!important; padding-bottom:0px!important;}
.p-tb-5 { padding-top:5px!important; padding-bottom:5px!important;}
.p-tb-10 { padding-top:10px!important; padding-bottom:10px!important;}
.p-tb-15 { padding-top:15px!important; padding-bottom:15px!important;}
.p-tb-20 { padding-top:20px!important; padding-bottom:20px!important;}
.p-tb-25 { padding-top:25px!important; padding-bottom:25px!important;}
.p-tb-30 { padding-top:30px!important; padding-bottom:30px!important;}
.p-tb-35 { padding-top:35px!important; padding-bottom:35px!important;}
.p-tb-40 { padding-top:40px!important; padding-bottom:40px!important;}
.p-tb-45 { padding-top:45px!important; padding-bottom:45px!important;}
.p-tb-50 { padding-top:50px!important; padding-bottom:50px!important;}
.p-tb-100 { padding-top:100px!important; padding-bottom:100px!important;}
.p-t-0 { padding-top:0px!important;}
.p-t-5 { padding-top:5px!important;}
.p-t-10 { padding-top:10px!important;}
.p-t-15 { padding-top:15px!important;}
.p-t-20 { padding-top:20px!important;}
.p-t-25 { padding-top:25px!important;}
.p-t-30 { padding-top:30px!important;}
.p-t-35 { padding-top:35px!important;}
.p-t-40 { padding-top:40px!important;}
.p-t-45 { padding-top:45px!important;}
.p-t-50 { padding-top:50px!important;}
.p-t-100 { padding-top:100px!important;}
.p-r-0 { padding-right:0px!important;}
.p-r-5 { padding-right:5px!important;}
.p-r-10 { padding-right:10px!important;}
.p-r-15 { padding-right:15px!important;}
.p-r-20 { padding-right:20px!important;}
.p-r-25 { padding-right:25px!important;}
.p-r-30 { padding-right:30px!important;}
.p-r-35 { padding-right:35px!important;}
.p-r-40 { padding-right:40px!important;}
.p-r-45 { padding-right:45px!important;}
.p-r-50 { padding-right:50px!important;}
.p-r-100 { padding-right:100px!important;}
.p-b-0 { padding-bottom:0px!important;}
.p-b-5 { padding-bottom:5px!important;}
.p-b-10 { padding-bottom:10px!important;}
.p-b-15 { padding-bottom:15px!important;}
.p-b-20 { padding-bottom:20px!important;}
.p-b-25 { padding-bottom:25px!important;}
.p-b-30 { padding-bottom:30px!important;}
.p-b-35 { padding-bottom:35px!important;}
.p-b-40 { padding-bottom:40px!important;}
.p-b-45 { padding-bottom:45px!important;}
.p-b-50 { padding-bottom:50px!important;}
.p-b-100 { padding-bottom:100px!important;}
.p-l-0 { padding-left:0px!important;}
.p-l-5 { padding-left:5px!important;}
.p-l-10 { padding-left:10px!important;}
.p-l-15 { padding-left:15px!important;}
.p-l-20 { padding-left:20px!important;}
.p-l-25 { padding-left:25px!important;}
.p-l-30 { padding-left:30px!important;}
.p-l-35 { padding-left:35px!important;}
.p-l-40 { padding-left:40px!important;}
.p-l-45 { padding-left:45px!important;}
.p-l-50 { padding-left:50px!important;}
.p-l-100 { padding-left:100px!important;}
/*upload btn*/
.ak-zupload-btn { cursor: pointer; font-weight: 400; padding: 6px 13px; position: relative; background: #e6e6e6; white-space: nowrap; display: inline-block; overflow:hidden;}
.ak-zupload-btn input[type="file"] { position: absolute; right: 0; top: 0; opacity: 0; filter: alpha(opacity=0); cursor: pointer; z-index:100;}
/*switch btn*/
.ak-switch-check input{display: none;}
.ak-switch-check i{display: inline-block;cursor: pointer;padding-right: 25px;transition: all ease 0.2s;-webkit-transition: all ease 0.2s;border-radius: 25px;border: solid 1px #ccc;}
.ak-switch-check i:before{display: block;content: '';width: 25px;height: 25px;border-radius: 25px;background: white;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);font-size: 8px;line-height: 25px;text-align:center;color:#747474;}
.ak-switch-check :checked + i{padding-right: 0;padding-left: 25px;background: #6cbff0;box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5), inset 0 0 40px #0093ea;-webkit-box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5), inset 0 0 40px #0093ea;}
.ak-switch-check i:before{content: "off";text-transform: uppercase;font-style: normal;}
.ak-switch-check i:after{content: "";position: absolute;}
.ak-switch-check :checked ~ i:before{content: "on";font-size:9px;color:#4684cf;}
/*form*/
.ak-form-wrap .form-control {
box-shadow: none;
border-radius: 0;
}
/*去掉移动端浏览器自动给input和textarea添加的内部阴影*/
input[type=text],textarea{-webkit-appearance: none;}
/*select 统一样式*/
.ak-zform-selectlabel {display: inline-block; margin:0!important; padding:0!important; font-weight:normal; width:100%; position:relative;}
select.ak-zform-select {-webkit-appearance: none;-moz-appearance: none; box-sizing:border-box; background:#fff;appearance:none;}
.ak-zform-selectlabel .select-icon {height:20px; right: 7px; top: 7px; width: 25px; position:absolute; background:#fff url(../images/ak-z-icon.png) no-repeat -305px -243px; cursor:pointer;pointer-events: none; z-index:999;}
.space-15 {
margin: 15px 0;
}
.space-20 {
margin: 20px 0;
}
.space-25 {
margin: 25px 0;
}
.space-30 {
margin: 30px 0;
}
body.modal-open {
padding-right: inherit !important;
}
.modal-backdrop {
z-index: 2040 !important;
}
.modal {
z-index: 2050 !important;
padding-top: 100px;
}
/*yeeoffice css*/
/*scroll修改过的滚动条样式 start*/
.content-zscroll{
overflow: auto;
position: relative;
padding:0;
-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;
}
.content-zscroll.hidden{ display: none; }
.content-zscroll hr{
margin-bottom: -10px;
border-top: 1px solid rgba(0,0,0,0.7);
}
.content-zscroll.light hr{
border-bottom: 1px solid rgba(255,255,255,0.6);
border-top: 1px solid rgba(0,0,0,0.1);
}
/*scroll修改过的滚动条样式 end*/
/*visible-xs hidden-xs*/
.visible-xs769 {
display: none;
}
.hidden-xs769 {
display: block;
}
@media (max-width: 768px){
.visible-xs769 {
display: block!important;
}
.hidden-xs769 {
display: none!important;
}
}
/*移动端浏览网页元素时,自动给input和textarea添加了内部阴影的效果*/
input,textarea{-webkit-appearance: none;}
input[type=checkbox]{-webkit-appearance:checkbox;cursor:pointer;}
input[type=radio] { -webkit-appearance: radio;cursor:pointer;}
/*select 统一样式*/
.ak-zform-selectlabel {display: inline-block; margin:0!important; padding:0!important; font-weight:normal; width:100%; position:relative;}
select.ak-zform-select {-webkit-appearance: none;-moz-appearance: none; box-sizing:border-box; background:#fff;appearance:none;}
.ak-zform-selectlabel .select-icon {height:20px; right: 7px; top: 7px; width: 25px; position:absolute; background:#fff url(../images/ak-z-icon.png) no-repeat -305px -243px; cursor:pointer;pointer-events: none; z-index:999;}
.ak-mcol-padding8 { padding-left:8px!important; padding-right:8px!important;}
@media (max-width:768px) {.col-md-4.col-sm-6.col-xs-12.item { width:100%!important;}}
/*Sky-Forms start--*/
.sky-form .label{display: block;margin-bottom: 6px;line-height: 19px;font-weight: 400;}
.sky-form .toggle{position: relative;display: block;}
.sky-form .radio,
.sky-form .checkbox{margin-bottom: 4px;padding-left: 27px;font-size: 15px;line-height: 27px;color: #404040;cursor: pointer;}
.sky-form .radio:last-child,
.sky-form .checkbox:last-child{margin-bottom: 0;}
.sky-form .radio input,
.sky-form .checkbox input{position: absolute;left: -9999px;}
.sky-form .radio i,
.sky-form .checkbox i{position: absolute;top: 5px;left: 0;display: block;width: 13px;height: 13px;outline: none;border-width: 2px;border-style: solid;background: #fff;}
.sky-form .radio i{border-radius: 50%;}
.sky-form .radio input + i:after,
.sky-form .checkbox input + i:after{position: absolute;opacity: 0;-ms-transition: opacity 0.1s;-moz-transition: opacity 0.1s;-webkit-transition: opacity 0.1s;}
.sky-form .radio input + i:after{content: '';top: 4px;left: 4px;width: 5px;height: 5px;border-radius: 50%;}
.sky-form .checkbox input + i:after{content: '\f00c';top: -1px;left: -1px;width: 15px;height: 15px;font: normal 12px/16px FontAwesome;text-align: center;}
.sky-form .radio input:checked + i:after,
.sky-form .checkbox input:checked + i:after{opacity: 1;}
.sky-form .toggle{margin-bottom: 4px;padding-right: 61px;font-size: 15px;line-height: 27px;color: #404040;cursor: pointer;font-weight: normal;}
.sky-form .toggle:last-child{margin-bottom: 0;}
.sky-form .toggle input{position: absolute;left: -9999px;}
.sky-form .toggle i{content: '';position: absolute;top: -4px;right: 0;display: block;width: 49px;height: 17px;border-width: 2px;border-style: solid;border-radius: 12px;background: #fff;
left:8px;;}
.sky-form .toggle i.col01{top:4px;left:0px;;}
.sky-form .toggle i:after{content: '停用';position: absolute;top: 2px;right: 8px;left: 8px;font-style: normal;font-size: 9px;line-height: 13px;font-weight: 700;text-align: left;color: #5f5f5f;}
.sky-form .toggle i:before{content: '';position: absolute;z-index: 1;top: 4px;right: 4px;display: block;width: 9px;height: 9px;border-radius: 50%;opacity: 1;-ms-transition: right 0.2s;-moz-transition: right 0.2s;-webkit-transition: right 0.2s;}
.sky-form .toggle input:checked + i:after{content: '启用';text-align: right;}
.sky-form .toggle input:checked + i:before{right: 36px;}
.sky-form .radio i,
.sky-form .checkbox i,
.sky-form .toggle i{border-color: #e5e5e5;-ms-transition: border-color 0.3s;-moz-transition: border-color 0.3s;-webkit-transition: border-color 0.3s;}
.sky-form .toggle i:before{background-color: #4684cf;}
.sky-form .rating label{color: #ccc;-ms-transition: color 0.3s;-moz-transition: color 0.3s;-webkit-transition: color 0.3s;}
.sky-form .radio:hover i,
.sky-form .checkbox:hover i,
/*.sky-form .toggle:hover i,{border-color: #8dc9e5;}*/
.sky-form .radio input:focus + i,
.sky-form .checkbox input:focus + i,
.sky-form .toggle input:focus + i{border-color: #2da5da;}
.sky-form .radio input + i:after{background-color: #2da5da;}
.sky-form .checkbox input + i:after{color: #2da5da;}
.sky-form .radio input:checked + i,
.sky-form .checkbox input:checked + i,
.sky-form .toggle input:checked + i{border-color: #2da5da;}
.sky-form .label{border-radius: 0;font-size: 100%;text-align: left;white-space: normal;color: inherit;}
.sky-form .radio,
.sky-form .checkbox{font-weight: 400;}
.sky-form .radio + .radio,
.sky-form .checkbox + .checkbox{margin-top: 0;}
.sky-form .input input{height: 34px;padding: 6px 12px;}
.sky-form .input input,
.sky-form .select select,
.sky-form .textarea textarea{border-width: 1px;font-size: 14px;color: #404040;}
.sky-form .select select{height: 33px;padding: 6px 10px;}
.sky-form .select-multiple select{height: auto;}
.sky-form .input input,
.sky-form .select select,
.sky-form .textarea textarea,
.sky-form .radio i,
.sky-form .checkbox i,
.sky-form .toggle i,
.sky-form .icon-append,
.sky-form .icon-prepend{border-color: #bbb;}
/*.sky-form .toggle i:before{background-color: #999;}
*/.sky-form .button{background: #72c02c;}
.sky-form .toggle i{width: 54px;height: 21px;border-width: 1px;}
.sky-form .toggle i:after{top: 3px;}
.sky-form .toggle i:before{top: 5px;right: 6px;}
.radio, .checkbox{margin-top: 0;}
.sky-form .radio i,
.sky-form .checkbox i{width: 17px;height: 17px;border-width: 1px;}
.sky-form .checkbox input + i:after{top: 2px;left: 0;font: normal 10px FontAwesome;}
.sky-form .radio input + i:after{top: 5px;left: 5px;background-color: #999;}
.sky-form .checkbox input + i:after{color: #999;}
.sky-form .radio input:checked + i,
.sky-form .checkbox input:checked + i,
.sky-form .toggle input:checked + i{border-color: #999;}
.sky-form .rating input:checked ~ label{color: #72c02c;}
.sky-form .input input:focus,
.sky-form .select select:focus,
.sky-form .textarea textarea:focus{border-color: #bbb;box-shadow: 0 0 2px #c9c9c9;}
.sky-form .radio input:focus + i,
.sky-form .checkbox input:focus + i,
.sky-form .toggle input:focus + i{border-color: #999;box-shadow: none;}
.sky-form .input:hover input,
.sky-form .select:hover select,
.sky-form .textarea:hover textarea{border-color: #999;}
.sky-form .radio:hover i,
.sky-form .checkbox:hover i,
.sky-form .toggle:hover i,
.sky-form .ui-slider-handle:hover{border-color: #999;}
.sky-form .input.state-disabled:hover input,
.sky-form .select.state-disabled:hover select,
.sky-form .textarea.state-disabled:hover textarea,
.sky-form .radio.state-disabled:hover i,
.sky-form .checkbox.state-disabled:hover i,
.sky-form .toggle.state-disabled:hover i{border-color: #bbb;}
.sky-form.ak-aqu-badge{padding-top:0;padding-bottom:0;margin-top:-5px;}
.sky-form .toggle input + i:before{ background-color:#a8a7a7;}
.sky-form .toggle input:checked + i:before{ background-color:#2da5da;}
/*Sky-Forms end--*/
/*分页 start*/
.pagination.ak-zcommon-pagelist>li>a, .pagination.ak-zcommon-pagelist>li>span{position: relative;float: left;padding: 5px 10px;font-size: 12px;line-height: 1.42857143;color: #555!important;text-decoration: none;background-color: #fff!important;border: 1px solid #ddd;margin-left:5px!important;margin-right:5px!important;border-radius:4px!important;}
.pagination.ak-zcommon-pagelist>a:focus, .pagination.ak-zcommon-pagelist>li>a:hover, .pagination.ak-zcommon-pagelist>li>span:focus, .pagination.ak-zcommon-pagelist>li>span:hover ,.pagination.ak-zcommon-pagelist>li>span:visited, .pagination.ak-zcommon-pagelist>li>span:visited{background-color: #fff!important;color: #0173f2!important;border-color: #0173f2!important;}
.pagination.ak-zcommon-pagelist>a.active{background-color: #fff!important;color: #0173f2!important;border-color: #0173f2!important;}
.pagination.ak-zcommon-pagelist > .active > a,
.pagination.ak-zcommon-pagelist > .active > span,
.pagination.ak-zcommon-pagelist > .active > a:hover,
.pagination.ak-zcommon-pagelist > .active > span:hover,
.pagination.ak-zcommon-pagelist > .active > a:focus,
.pagination.ak-zcommon-pagelist > .active > span:focus{z-index: 2;color: #0173f2!important;cursor: default;background-color: #fff!important;border-color: #0173f2!important;}
.ak-zpagelisticon{width:20px;height:21px;display:inline-block;background-image:url(../images/ak-z-icon.png);cursor:pointer; float:left;}
.ak-zpagelisticon.left{background-position:0 -245px;}
.ak-zpagelisticon.right{background-position:-27px -245px;}
.pagination.ak-zcommon-pagelist>li:first-child>a, .pagination.ak-zcommon-pagelist>li:first-child>span{padding:3px;}
.pagination.ak-zcommon-pagelist>li:last-child>a, .pagination>li:last-child>span{padding:3px;}
/*分页 end*/
/*=====loading start=====*/
.zpage-loader{ display:none;width:100%;height:100%;position:fixed;top:0;left:0;background:rgba(250,250,250,0.8);z-index:100000}
.sk-wave-loading {
width: 50px;
height: 30px;
text-align: center;
font-size: 10px; top:50%;left:50%; margin:-15px 0 0 -25px; position:absolute;}
.sk-wave-loading .sk-rect {
background-color: #4684cf;
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: sk-waveStretchDelay 1.2s infinite ease-in-out;
animation: sk-waveStretchDelay 1.2s infinite ease-in-out; }
.sk-wave-loading .sk-rect1 {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s; }
.sk-wave-loading .sk-rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-wave-loading .sk-rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-wave-loading .sk-rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-wave-loading .sk-rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
@-webkit-keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }
@keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }
.sk-wave-text { color:#4684cf;}
.ak-zloading-block { display:block!important;}
.ak-zloading-none { display:none!important;}
/*=====loading end=====*/
.ak-znews-addsort-modal .control-label.ak-form-label {
text-align: left!important;
font-weight: normal;
}
.ak-zicon.ak-navphoneicon{ background-position:-339px -18px; margin-right:5px;margin-top:-4px;}
.ak-zicon.ak-navkonwicon{ background-position:-304px -18px; margin-right:5px;margin-top:-4px;}
/*modal*/
.col-md-12.ak-back-header.clearfix { padding-left:0; padding-right:0;}
/*modal start*/
.ak-min-fullwidth-modal .modal-body { background:#f5f5f5; padding:15px 30px;}
.ak-min-fullwidth-modal .modal-body.col01 {background:transparent;}
.ak-min-fullwidth-modal .modal-content { background:#fff!important;}
@media (max-width:768px) {
.ak-min-fullwidth-modal .modal-dialog { margin:0;}
.ak-min-fullwidth-modal .modal-content {min-height: 100%; height:auto;
border-radius: 0!important;}
.add-doc-icon {margin-top:20%;}
}
@media (max-width:768px) {.ak-min-fullwidth-modal .modal-header .close{ margin-top:5px; margin-right:5px; float:left;}}
.ak-header-btnsm { padding:4px 7px; font-size:12px;}
.ak-zdl-createbtn {padding: 6px 13px; background:#629cfa; color:#fff; border:none;}
/*.ak-zdol-changebg-btn:hover {background:rgba(51, 51, 51, 0.6) url(../images/photo2.png) no-repeat center center;}*/
.ak-zdl-createbtn.cancel { background:#f3f3f3; color:#555; margin-left:5px;}
.form-control {
box-shadow: none;
/*border-radius: 0 !important;*/
}
.ak-min-fullwidth-modal .modal-content { border-radius:0!important;}
@media (min-width: 992px) {.ak-min-fullwidth-modal .modal-dialog { width:800px; /*margin-top:15%;*/}}
@media (min-width: 768px) and (max-width:992px){
.ak-min-fullwidth-modal .modal-dialog {
width: 90%;
}}
.ak-min-fullwidth-modal .close { width:16px; height:16px; background:url(../images/ak-z-icon.png) -150px -1px; opacity: 1;color:transparent;margin-top:4px; outline:medium none;}
/*.ak-min-fullwidth-modal .close:foucs { outline:none;}*/
.ak-zdl-createbtn {padding: 5px 13px; background:#629cfa; color:#fff; margin-left:15px; border:solid 1px #4389f9;}
/*.ak-zdol-changebg-btn:hover {background:rgba(51, 51, 51, 0.6) url(../images/photo2.png) no-repeat center center;}*/
.ak-zdl-createbtn.cancel { background:#f3f3f3; color:#555; border:solid 1px #ddd;}
@media (max-width:768px) {.ak-min-fullwidth-modal .close {background:url(../images/ak-z-icon.png) -186px -2px;}
.ak-min-fullwidth-modal .modal-content { background:#f5f5f5!important;}
.ak-min-fullwidth-modal .modal-content .modal-header {background:#fff!important;}}
@media (max-width:768px) {.ak-min-fullwidth-modal .modal-body { padding:15px;}}
/*modal end*/
/*visible-xs hidden-xs*/
.visible-zxs {
display: none!important;
}
.hidden-zxs {
display: block!important;
}
@media (max-width: 768px){
.visible-zxs {
display: block!important;
}
.hidden-zxs {
display: none!important;
}
}
h1{font-size: 28px;line-height: 35px;}
h2{font-size: 24px;line-height: 33px;}
h3{font-size: 20px;line-height: 27px;}
h4{line-height: 25px;}
h5{line-height: 20px;}
h6{line-height: 18px;}
h1, h2, h3, h4, h5, h6{color: #555;margin-top: 5px;text-shadow: none;font-weight: normal;font-family:Arial,'Microsoft yahei';}
h1 i, h2 i, h3 i, h4 i, h5 i, h6 i{margin-right: 5px;}
p,
li,
li a,
label{color: #555;}
.ak-zdol-icon {
width: 25px;
height: 25px;
display: inline-block;
float: left;
/*background: url(../images/ak-common-icon.png) no-repeat 0 0;*/
margin-right: 10px;
cursor: pointer;
}
.ak-zdol-topsropbtn span {
margin-top: 0!important;
}
.ak-akdetail-titlewrap span {
float: left;
line-height: 25px;
margin-top: 4px;
}
.ak-zdol-icon.iconmore-light {
width: 20px;
height: 20px;
background: url(../images/ak-z-icon.png) no-repeat -304px -206px;
}
.ak-zgrey-back {
display: inline-block;
background: url(../images/ak-z-icon.png) -304px -55px;
background-repeat: no-repeat;
width: 25px;
height: 25px;
vertical-align: middle;
cursor: pointer;
margin-right: 0!important;
float: left;
margin-top: 14px;
}
.btn {
box-shadow: none;
}
.ak-zdol-topsropbtn {
width: 30px;
height: 30px;
padding: 6px 12px!important;
background: transparent;
border: none;
cursor: pointer;
margin-top: 10px;
}
.ak-zdol-searchbox {position: relative;
width: 230px; margin-top:11px;}
.ak-zdol-searchbox input[type="text"] {
background:#fff none repeat scroll 0 0;
border: 1px solid #d4d4d4;
color: #797979;
display: inline-block;
font-size: 0.975em;
outline: medium none;
padding: 0 2px 0 30px;
width: 100%;
height: 28px;
}
.ak-zdol-searchbox span.searchicon {
background:#fff url("../images/ak-z-icon.png") no-repeat scroll 0 0;
border: 0 none;
display: inline-block;
height: 16px;
left: 6px;
outline: medium none;
position: absolute;
top: 6px;
width: 16px;
}
/*back to-top start*/
#topcontrol{color: #fff;z-index: 99;width: 30px;height: 30px;font-size: 20px;background: #222;position: relative;right: 14px !important;bottom: 11px !important;border-radius: 3px !important;}
#topcontrol:after{top: -2px;left: 8.5px;content: "\f106";position: absolute;text-align: center;font-family: FontAwesome;}
/* to-top end*/
/*upload*/
.ak-upload {
font-size: 22px;
position: absolute;
cursor: pointer;
color: #fff;
border: none;
overflow: hidden;
display: inline-block;
}
.ak-zdol-changebg-btn {
width: 50px;
height: 50px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-o-border-radius: 50%;
-ms-border-radius: 50%;
border-radius: 50%;
position: absolute;
right: 15px;
bottom: 20px;
/*background: rgba(0, 0, 0, 0.6) url(../images/photo2.png) no-repeat center center!important;*/
border: none;
outline: none;
cursor: pointer;
z-index: 1046;
}
.ak-zdol-changebg-btn:hover {
/*background: rgba(51, 51, 51, 0.6) url(../images/photo2.png) no-repeat center center!important;*/
}
.ak-upload input {
position: absolute;
font-size: 100px;
right: 0;
top: 0;
opacity: 0;
filter: alpha(opacity=0);
cursor: pointer; z-index: 100;
}
@media (max-width: 768px){
.modal-dialog {
position: absolute;
width: auto;
margin: 10px;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
.ak-required { color: red;}
/*sm modal*/
@media (min-width: 769px) {.zsm-modal .modal-dialog{ width: 400px!important;margin-top:13%;}
.zsm-modal .modal-body { padding:15px; background: #fff; }.zsm-modal .modal-dialog {margin-top:13%;}
}
.zsm-modal .close { width:16px; height:16px; background:url(../images/ak-z-icon.png) -150px -1px; opacity: 1;color:transparent;margin-top:4px; outline:medium none;}
/*.zsm-modal .close:foucs { outline:none;}*/
@media (max-width:768px) {.zsm-modal .modal-dialog{margin-top:5%;}}
.ak-zsm-modal .modal-content {
border-radius: 0!important;
}
@media (min-width: 768px){
.ak-zsm-modal .modal-sm { width:500px;}
.ak-zsm-modal .modal-dialog { margin-top:15%;}
.ak-zsm-modal10 .modal-dialog { margin-top:10%;}
}
.ak-zsm-modal .close {
width: 16px;
height: 16px;
/*background: url(../../images/ak-z-icon.png) -150px -1px;*/
opacity: 1;
color: transparent;
margin-top: 4px;
outline: medium none;
}
.ak-zgrey-back.ak-zdol-nback { display:none;}
@media (max-width: 768px){
.ak-zsm-modal .modal-header .close {
margin-top: 5px;
margin-right: 5px;
float: left;
}
.ak-zsm-modal .close {
/*background: url(../../images/ak-z-icon.png) -186px -2px;*/
}
.ak-zsm-modal .modal-content {
min-height: 100%;
}}
@media (max-width: 992px){
.ak-zgrey-back.ak-zdol-nback { display:block;}
}
ul li a:hover{background-color: #35b0ee; }
/* */
body{margin:0;padding:0;overflow-x:hidden;}
html, body{height:100%;}
img{border:none;}
*{font-family:'微软雅黑';font-size:12px;}
dl,dt,dd{display:block;margin:0;padding:0;}
a{text-decoration:none;}
#bg{background-image:url(../images/dotted.png);}
.container{width:100%;height:100%;margin:auto;}
/*left*/
.leftsidebar_box{float:left;width:150px;height:auto !important;overflow:visible !important;position:fixed;height:100% !important;background-color:#0277bd;}
.line{width:100%;background-image:url(../images/line_bg.png);background-repeat:repeat-x;}
.leftsidebar_box dt{padding-left:40px;padding-right:10px;background-repeat:no-repeat;background-position:10px center;color:#f5f5f5;font-size:14px;position:relative;line-height:48px;cursor:pointer;margin-bottom:1px;}
.leftsidebar_box dd{background-color: #0277bd;}
.leftsidebar_box dd a{display:block;color:#f5f5f5;line-height:20px;padding:7px 0 7px 40px!important;}
.leftsidebar_box dd a:hover {background-color:#3992D0;}
.leftsidebar_box dt img{position:absolute;right:10px;top:20px;}
.functiontest dt{background-image:url(../images/system.png)}
.interfacetest dt{background-image:url(../images/channel.png)}
.channel dt{background-image:url(../images/channel.png)}
.tools dt{background-image:url(../images/source.png)}
.cloud dt{background-image:url(../images/cloud.png)}
.setting dt{background-image:url(../images/syetem_management.png)}
.source dt{background-image:url(../images/statistics.png)}
.statistics dt{background-image:url(../images/app.png)}
.leftsidebar_box dl dd:last-child{padding-bottom:10px;}
================================================
FILE: automatic/static/css/ak-schedule.css
================================================
.ak-zper-ltopbtnbox{background:#fafafa;height:50px;position:relative;border-bottom: solid 1px #eee;box-shadow: 0 0 8px #ddd;border-right: solid 1px #ddd;}
.ak-zper-navbtn{width:25px;height:15px;display:inline-block;cursor:pointer;margin:17px 0 0 15px;}
.ak-zper-adminbox{height:60px;padding-left:8px;}
.ak-zper-adminbox .img-box{width:38px;height:38px;overflow:hidden;display:inline-block;cursor:pointer;border-radius:50%;margin:11px 10px 6px 10px;float:left;}
.ak-zper-adminbox .img-box img{display: block;max-width: 100%;height: auto;min-width:100%;min-height:100%;}
.ak-zper-adminbox .name{height:60px;line-height:60px;font-size:14px;cursor:pointer;float:left;color: #f0f0f0}
.al-zper-dropdownicon{width:20px;height:30px;display:inline-block;cursor:pointer;margin-top:15px;float:left;}
.ak-zpericon{width:20px;height:20px;display:inline-block;cursor:pointer;float:left;}
.ak-zper-bellicon{width:20px;height:20px;margin-right:10px;font-size:18px;display:inline-block;opacity:0.7;}
.ak-zper-chaticon{width:20px;height:20px;float:right;margin-top:20px;margin-right:20px;}
.ak-zper-inbox-title{height:61px;background:#fafafa;color:#555;border-bottom: solid 1px #eee;/*box-shadow: 0 0 8px #ddd;*/position:relative;}
.ak-zper-inbox-title .inbox-text{font-size:16px;height:50px;line-height:50px;margin-left:15px;cursor:pointer;}
.ak-zper-inbox-con{padding:15px;}
.ak-zper-addtask-box{height:50px;background-color:rgba(118,148,116,0.85);padding:0 50px 0 40px;position:relative;margin-bottom:10px;cursor:pointer;}
.ak-zper-addtask-input{background:transparent;border-color:transparent;outline:none;color:#fff;font-size:14px;width:100%;height:50px;line-height:50px;padding-left:5px;}
.ak-zper-addicon{background-position:-353px -206px;position:absolute;top:15px;left:15px;}
.ak-zper-inbox-list.active{background:#e1f2fe;}
.ak-zper-complete{display:inline-block;padding:5px 10px;background:#668964;cursor:pointer;color:#fff;margin-top:20px;}
.ak-zper-inbox-listnew.conplete .ak-zper-inbox-list{background-color:rgba(255,255,255,1);}
.ak-zper-leftbox,.ak-zper-midbox,.ak-zper-rightbox{padding-bottom: 9999px;margin-bottom: -9999px;overflow:hidden;padding-left:0!important;padding-right:0!important;min-height:100%;}
.ak-zper-midbox{background:#fff}
.ak-zper-remind-title{padding:10px 35px 10px 40px;height:auto;position:relative;}
.ak-zper-remind-title .check-box{position:absolute;top:10px;left:15px;}
.ak-zper-inboxstar.remaindbox{position:absolute;right:10px;top:13px;}
.ak-zper-remind-title .text{font-size:16px;}
.ak-zper-remindicon{width:25px;height:25px;display:inline-block;cursor:pointer;position:absolute;top:10px;left:10px;}
.ak-zper-canicon{background-position:-4px -4px;}
.ak-zper-remind-list{padding-left:40px;position:relative;}
.ak-zper-remind-list .right-text{border-bottom: solid 1px #ddd;min-height:40px;}
.ak-zper-remind-list .right-text input{border:none;background:transparent;outline:none;height:40px;padding-left:5px;width:100%;font-weight: normal;cursor:pointer;}
.ak-zper-remind-list .right-text textarea{border:none;background:transparent;outline:none;height:auto;padding-left:5px;width:100%;}
.ak-zper-leftbox, .ak-zper-rightbox{background:#fafafa;}
.ak-zper-alarm-clockicon{background-position:-4px -51px;}
.ak-zper-sight-addicon{background-position:-4px -99px;}
.ak-zper-sight-editicon{background-position:-4px -148px;}
.ak-zper-sight-fileicon{background-position:-4px -196px;}
.ak-zperleftnav-ul{margin:0;padding:0;list-style:none;}
.ak-zperleftnav-ul .list-group-item{cursor:pointer;border:none;font-size:14px;cursor:pointer;background:transparent;display: block;padding: 10px 15px;}
.ak-zperleftnav-ul .list-group-item:hover{cursor:pointer;}
.ak-zperleftnav-ul .list-group-item:first-child{border-top-left-radius: 0px;border-top-right-radius: 0px;}
.ak-zperleftnav-ul .list-group-item:last-child{border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;}
.ak-zperleftnav-ul .list-group-item.active, .ak-zperleftnav-ul .list-group-item.active:focus, .ak-zperleftnav-ul .list-group-item.active:hover, .ak-zperleftnav-ul .list-group-item:hover{z-index: 2;color: #555;background: #cce8ff;}
.ak-zper-navicon{width:25px;height:25px;display:inline-block;cursor:pointer;float:left;margin-right:10px;}
.ak-zper-navicon img{margin:0 auto;}
.ak-zper-nav-smred{width:25px;height:25px;font-size:12px;color:red;margin-right:5px;background:#ffd6d6;float:right;display:inline-block;border-radius:50%;text-align:center;line-height:25px;text-align:center;}
.ak-zper-nav-smgrey{width:25px;height:25px;font-size:12px;color:#787878;float:right;display:inline-block;line-height:25px;text-align:center;}
.ak-zperleftnav-ul .list-group-item.active .ak-zper-nav-smred , .ak-zperleftnav-ul .list-group-item.active:focus .ak-zper-nav-smred , .ak-zperleftnav-ul .list-group-item.active:hover .ak-zper-nav-smred , .ak-zperleftnav-ul .list-group-item:hover .ak-zper-nav-smred{background:#d96e6c;color:#fff;}
.ak-zperleftnav-ul li a{display: block;}
.ak-zperleftnav-ul .secondary{list-style:none;padding:0;margin:0;display:none;}
.ak-zperleftnav-ul li a{display: block;padding: 10px 15px;}
.ak-zper-inboxback{width:25px;height:25px;display:none;float:left;margin:12px 0 0 5px;cursor:pointer;}
.ak-zper-remindback{width:25px;height:25px;display:none;float:left;cursor:pointer;position: absolute;top: 12px;left: 10px;}
.ak-zper-md-3, .ak-zper-md-6, .ak-zper-md-9, .ak-zper-md-12{position: relative;min-height: 1px;padding-right: 15px;padding-left: 15px;width:100%;}
.ak-zper-leftbox{float:left;width:150px;}
/*.ak-zper-midbox{float:left;width:100%;}*/
.ak-zper-rightbox{float:left;width:100%;}
.ak-zper-rightbox-block{display:block!important;}
.ak-zper-rightbox-none{display:none;}
/*左、右、中 三块布局的宽度*/
@media (min-width: 1200px){.ak-zper-md-3,.ak-zper-md-25, .ak-zper-md-6, .ak-zper-md-9, .ak-zper-md-12{float: left;}
.ak-zper-md-3{width: 20%;}
.ak-zper-md-6{width: 55%!important;}
.ak-zper-md-9{width: 80%;}
.ak-zper-md-25{width: 25%;}
/*.ak-zper-leftbox{width:15%;}*/
/*.ak-zper-midbox{width:85%;}*/
.ak-zper-rightbox{width:25%;}}
@media (min-width:992px) and (max-width:1199px){.ak-zper-md-3, .ak-zper-md-6, .ak-zper-md-9, .ak-zper-md-12{float: left;}
.ak-zper-md-3{width: 25%;}
.ak-zper-md-6{width: 50%!important;}
.ak-zper-md-9{width: 50%;}
.ak-zper-leftbox{width:25%;}
.ak-zper-midbox{width:75%;}
.ak-zper-rightbox{width:25%;}}
@media (max-width:991px){.ak-zper-remind-title .check-box{display:none;}
.ak-zper-inboxback{display:inline-block;}
.ak-zper-remindback{display:inline-block;}
.ak-zper-leftbox{display:none;}
.ak-zper-rightbox{display:none;}
.ak-zper-threebox-none{display:none!important;}
.ak-zper-threebox-block{display:block!important;}}
.ak-zper-shareicon{width:20px;height:20px;display:inline-block;cursor:pointer;margin:5px 0 5px 0;}
.ak-zper-sorticon{width:20px;height:20px;display:inline-block;cursor:pointer;font-size:16px;color:#555;line-height:20px;font-weight:lighter;margin:5px 0 5px 0;opacity:0.85;}
.ak-zper-sortbtnbox{display:inline-block;float:right;width:30px;text-align:center;height:50px;font-size:12px;color:#555;margin-right:10px;cursor:pointer;}
.ak-zper-navbtext{color:#555;font-size:16px;height:50px;line-height:50px;margin-left:10px; cursor:pointer;}
.ak-zper-detailed-listadd{width:25px;height:25px;display:inline-block;cursor:pointer;margin:17px 5px 0 10px;background-position: -386px -206px;}
.ak-zper-midbox.ak-zper-md-6 .ak-zper-inbox-title{border-right: solid 1px #ddd;}
@media (min-width:992px) and (max-width:1199px){.ak-zper-inbox-list .title{width:70%;}}
.ak-zper-inbox-list .btn-box{position:absolute;top:0;right:0;bottom:0;padding:8px 8px 0px 8px;background:#fff;}
.ak-zper-inbox-list.active .btn-box{background: #e1f2fe;}
.ak-zper-inbox-listnew.conplete .ak-zper-inbox-list{opacity:0.7;}
.ak-zper-inbox-listnew.conplete .ak-zper-inbox-list .title{text-decoration:line-through;}
.ak-zper-remaind-taskcheck{width: 25px;height: 25px;display: inline-block;cursor: pointer;position: absolute;top: 10px;left: 10px;}
.ak-zper-remind-list .subtask-text{display:inline-block;margin-top:13px;margin-left:5px;}
.ak-zper-remind-list .right-text.subtask-textbox{min-height:30px;border-color:transparent;position:relative;padding-right:30px;}
.ak-zper-remind-list .right-text.subtask-textbox .closebtn{position:absolute;width:20px;height:20px;display:inline-block;background-position: -220px 5px;right:0;top:10px;right:10px;cursor:pointer;}
.ak-zper-remind-list .right-text .ak-zper-remind-upload{width:100%;height:40px;display:inline-block;cursor:pointer;}
.ak-zper-remind-list .right-text .ak-zper-remind-upload input{position: absolute;font-size: 100px;right: 0;top: 0;opacity: 0;filter: alpha(opacity=0);cursor: pointer;z-index:100;height:40px;cursor:pointer;}
.ak-zper-remind-list .right-text .ak-zper-remind-upload .add-text{color:#a9a9a9;font-size:12px;line-height:40px;}
.ak-zper-remind-list .right-text .ak-zper-remind-upload:hover .add-text{color:#a9a9a9;}
.ak-zper-upload-smbox{border: solid 1px #ddd;height:60px;position:relative;margin:8px 10px 8px 0;; padding:0 30px 0 65px;cursor:pointer;}
.ak-zper-upload-smbox .img-box{width:60px;height:60px;overflow:hidden;cursor:pointer;display:inline-block;position:absolute;top:0;left:0;}
.ak-zper-upload-smbox .img-box img{min-width:100%;min-height:100%;}
.ak-zper-upload-smbox .title{font-size:14px;color:#555;margin-top:8px;margin-bottom:5px;overflow:hidden; white-space:nowrap !important;text-overflow:ellipsis;}
.ak-zper-upload-smbox .time{font-size:12px;color:#a9a9a9;overflow:hidden; white-space:nowrap !important;text-overflow:ellipsis;}
.ak-zper-upload-smbox .closebtn{cursor:pointer;position:absolute;width:20px;height:20px;display:inline-block;background-position: -220px 5px;right:0;top:20px;right:10px;}
.ak-zper-alarm-shareicon{opacity:0.8;}
.ak-zper-remind-list .right-text.reply{border-color:transparent;padding-right:100px;padding-top:8px;position:relative;}
.ak-zper-remind-list .right-text.reply .title{font-weight:600;}
.ak-zper-remind-list .right-text.reply .time-right{padding-right:10px;position:absolute;top:15px;right:0;width:100px;overflow:hidden;white-space:nowrap !important;text-overflow:ellipsis;-o-text-overflos:ellipsis;color:#a9a9a9;text-align:right;}
.ak-zper-commentsbox{border:solid 1px #ddd;margin:10px 15px;height:40px;line-height:40px;padding-left:35px;position:relative;}
.ak-zper-commentsbox input{border:none;width:100%;background:transparent;}
.ak-zpericon.ak-zper-chaticon.commments{position:absolute;top:10px;left:10px;margin:0;}
.ak-zper-fix-btnbox{height:60px;padding:0 10px;text-align:center;color:#555;line-height:50px;position:relative;}
.ak-zpericon.ak-zper-fixback-icon{width:25px;height:25px;position:absolute;top:12px;left:10px;display:none;}
.ak-zpericon.ak-zper-fixdelete-icon{width:25px;height:25px;position:absolute;top:12px;right:10px;}
.ak-zper-fixedbox{height:100px;padding:15px 0;}
.ak-zper-rightbox{position:relative;}
.list-group-item.ak-zper-list-toggle.ak-zper-listgrey{background:#f3f3f3;}
.list-group-item.ak-zper-list-toggle.ak-zper-listgrey .secondary .active,.list-group-item.ak-zper-list-toggle.ak-zper-listgrey .secondary li:hover{background:#cce8ff;}
.ak-zperleftnav-ul .secondary li{padding-left:30px;}
.ak-zperleftnav-ul .list-group-item.ak-zper-list-toggle.ak-zper-listgrey.active, .ak-zperleftnav-ul .list-group-item.ak-zper-list-toggle.ak-zper-listgrey.active:focus, .ak-zperleftnav-ul .list-group-item.ak-zper-list-toggle.ak-zper-listgrey.active:hover, .ak-zperleftnav-ul .list-group-item.ak-zper-list-toggle.ak-zper-listgrey:hover{background:#f3f3f3;}
@media (min-width:992px){.ak-zper-remindback{display:none;}
.ak-zpericon.ak-zper-fixback-icon{display:block!important;}}
.ak-zper-remind-list .right-text .ak-time-icon{position: absolute;right: 1px;top: 0;width: 29px;height: 28px;line-height: 28px;text-align: center;cursor:pointer; border:none;}
.ak-zper-remind-list .right-text .input-za.ak-append-box{width:100%;}
.ui-datepicker-prev, .ui-datepicker-next{top:15px!important;}
.form-control.ak-zperrepeat-select{border:none;background:transparent;height:40px;color:#555;font-size:12px;padding-left:0;line-height:40px;cursor:pointer;}
.form-control.ak-zperrepeat-select:focus{border:none!important;box-shadow:none;outline:none;}
.ak-zper-repeaticon{}
.input-group-addon{background:transparent;border:none;cursor:pointer;}
.ak-zper-remind-list .right-text input.form-control:focus{border:none!important;box-shadow:none;outline:none;}
.form-control.ak-zperrepeat-select option{font-size:14px;}
.ak-zmemo-modalback{width: 25px;height: 25px;background: url(../images/zkonw-back.png) no-repeat center center;display:inline-block;float: left;margin:0 0 0 -5px;cursor: pointer;}
.ak-min-fullwidth-modal .close.close-back{width: 25px;height: 25px;background: url(../images/zkonw-back.png) no-repeat center center;opacity: 1;color: transparent;margin-top: 4px;outline: medium none;float: left;margin:0;}
.ak-zmec-listedit{width: 25px;height: 25px;display: inline-block;cursor: pointer;margin: 11px 5px 0 10px;background-position: -360px -62px;}
.ak-zmemo-leftnav.right-border.right-border{border-right: solid 1px #ddd;}
.ak-zmemo-leftnav.right-border .ak-zper-ltopbtnbox{border-right:none;}
.ak-zweichat-searchbox{padding:10px 15px;border-bottom: solid 1px #ddd;}
.ak-zweichat-searchbox .ak-zdol-searchbox{width:100%;margin-top:0;}
.ak-zper-rowpointer{width: 30px;height: 30px;display: inline-block;cursor: pointer;margin-right:5px;}
.ak-zpernav-more-btn{width: 25px;height: 25px;padding: 6px 12px!important;background: transparent;border: none;cursor: pointer;}
.ak-zperleftnav-ul.ak-zper-listgrey .list-group-item{background: #f3f3f3;}
.ak-zperleftnav-ul.ak-zper-listgrey .list-group-item:hover{z-index: 2;color: #555;background: #cce8ff;}
/*schedule css*/
.ak-jsch-border{ border-right:#d7d7d7 1px solid;}
.ak-zper-ltopbtnbox.ak-jsch-top{ box-shadow:none;border-right:none; border-color:#d7d7d7;}
.ak-jsch-left-ul{ padding:0; margin:0; margin-top:10px;margin-bottom:10px; list-style:none;}
.ak-jsch-left-ul li{ padding:8px 15px; font-size:14px; cursor:pointer;}
.ak-jsch-left-ul li:hover{ background-color:#CCE8FF;}
.ak-jsch-left-ul li p.ak-jsch-li-text{padding:0; margin:0; display:inline-block; margin-left:20px; font-size:16px;}
.ak-jsch-li-img{ display:inline-block;}
.ak-jsch-block{ background-color:#f0f0f5; border-top:#d7d7d7 1px solid;border-bottom:#d7d7d7 1px solid;}
.ak-jsch-block h3{ padding:0; margin:0; padding:10px; font-size:16px;}
.ak-jsch-searchbox{padding:15px 10px;border-bottom:#d7d7d7 1px solid;}
.ak-jsch-searchbox .ak-zdol-searchbox{margin:0 auto; width:100%;}
.ak-jsch-left-ul li span.ak-sch-icon{width:20px;height:20px;border-radius:3px; vertical-align:middle;}
.ak-sch-icon.checkbox1-icon{ background-color:#e57b72;}
.ak-sch-icon.checkbox2-icon{ background-color:#4184f3;}
.ak-sch-icon.checkbox3-icon{ background-color:#7885ca;}
.ak-sch-icon.checkbox4-icon{ background-color:#b29cda;}
.ak-zper-midbox.ak-jsch-mid{ background-image:none; margin-left:150px;}
.ak-zper-inbox-title.ak-jsch-title{ position:relative;padding-left:10px; box-shadow:none; border-color:#d7d7d7;background-color:#fff;}
.ak-jsch-rightbox{ position:absolute; right:0;}
.ak-jsch-title .ak-sch-icon{width:26px;height:30px;vertical-align:middle; cursor:pointer;}
.ak-zper-inbox-title.ak-jsch-title .inbox-text{margin-left:0;}
.ak-jsch-row3 span{ line-height:50px;}
.ak-jsch-time span{ display:inline-block; padding:0 20px;}
.ak-jsch-time span a{ color:inherit;}
.ak-jsch-time span.selected{ color:#006ec4; border-bottom:#006ec4 3px solid; line-height:44px;}
.ak-jsch-jia{ margin-right:15px; margin-top:10px;display:inline-block; width:30px; height:30px;cursor:pointer;}
.ak-jsch-calendar{ width:100%; table-layout:fixed;}
.ak-jsch-calendar th{ font-weight:normal; text-align:center; line-height:30px;border-bottom: #e7e9ea 1px solid;}
.ak-jsch-calendar th,.ak-jsch-calendar td{font-size:14px;}
.ak-jsch-calendar th.current{ color:#0978c7;}
.ak-jsch-calendar td.current{ background-color:#f4f9fd;}
.ak-jsch-calendar tr td:first-child{ text-align:right;}
.ak-jsch-calendar tr.ak-jsch-tr{ text-align:right;border-bottom:2px #dfdfdf solid; height:60px;}
.ak-jsch-calendar tbody td{ position:relative;border-bottom:#e7e9ea 1px solid;height:30px;}
.ak-jcalendar-td{ float:left;width:98%; margin:0 auto;border-left:#c0392b 2px solid; background-color:#f1c5c0; color:#932c22; text-align:left; height:30px; overflow:hidden;font-size:12px;line-height:30px;overflow:hidden;cursor:pointer}
.ak-jcalendar-time{position:absolute; left:42px;width:calc( 100% - 42px);}
.ak-jcalendar-line {position:relative;border-bottom: #f8c8c9 2px solid;}
/*新增*/
.ak-jsch-wrapbox{ position:relative;}
.ak-jcalendar-h1{ height:2px;}
.ak-jcalendar-time .col-01{ width:14.3%;}
.ak-jcalendar-time .col-02{ width:85.7%;}
.ak-jsch-red{background-color:#e52126;}
.ak-jsch-light{ background-color:#f8c8c9;}
.ak-jcalendar-td.col-01{ width:10%;}
.ak-jcalendar-td.col-02{ width:20%;}
.ak-jcalendar-td.col-03{ width:30%;}
.ak-jsch-event .ak-jcalendar-td.col-02{ width:20%;}
.ak-jsch-event .ak-jcalendar-td.col-03{ width:30%;}
.ak-jsch-mt12{ margin-top:12px;}
.ak-jsch-left-ul .ak-zpernav-more-dropdown li:hover{ background-color:transparent;}
.ak-jsch-left-ul .ak-zpernav-more-dropdown li{ padding:0;}
.ak-jsch-left-ul .ak-zpernav-more-dropdown li a{padding:10px 15px;}
.ak-jsch-block .ak-zper-detailed-listadd{ margin-top:14px;}
.ak-zdol-trsmbtn.iconedit-sm {
width: 26px;
background-position: -111px -56px;
margin-right: 10px;
}
.ak-zdol-trsmbtn.icondelete-sm {
width: 26px;
background-position: -148px -56px;
margin-right: 10px;
}
.ak-zmemo-modal-tabnav.nav.ak-jsch-nav>li>a{ padding:6px 0; display: inline-block;}
.ak-jcalendar-time.ak-jmin-47{ top:294px;}
.ak-jcalendar-minute{ position:absolute; right:0;color:#e6373c; font-size:12px; line-height:12px;}
.ak-jcalendar-minute.ak-jmin-47{margin-top:-14px;}
.ak-jcalendar-point{ position:absolute;top:-3px;width:8px; height:8px;border-radius:4px; background-color:#e63237;}
.ak-jcalendar-td.ak-jsch-h2{ height:60px;}
.ak-jsch-dropdown .ak-sch-icon.btn{ border:none;}
.ak-jsch-dropdown .dropdown-menu{ left:auto; right:0;}
.btn-group.ak-jsch-dropdown{vertical-align:baseline;}
.ak-jsch-dropdown.btn-group.open .dropdown-toggle{box-shadow:none;}
.ak-jsch-dropdown.open>.dropdown-toggle.btn-default{ background-color:transparent;}
@media(min-width:769px){.ak-jsch-row3.ak-zper-fix-btnbox{ text-align:left;}.ak-jsch-dropdown{ display:none;}.ak-jsch-row3:first-child{ width:44%;}}
@media(max-width:991px){.ak-jsch-row3.ak-zper-fix-btnbox{ padding-left:36px;}}
@media(max-width:768px){.ak-jsch-row3.ak-zper-fix-btnbox{width:calc(100% - 84px);}}
@media(max-width:440px){.ak-jsch-calendar th span{ display:block;}.ak-zper-inbox-title.ak-jsch-title{ padding-left:0;}}
/*schedule-day css*/
.ak-jsch-total{height:60px;border-bottom:2px #dfdfdf solid;}
.ak-jsch-tablewrap{border-bottom:#e7e9ea 1px solid;}
.ak-jsch-div{ position:relative;height:60px;border-bottom:#e7e9ea 1px solid;}
.ak-jsch-hour{ position:absolute;width:50px;font-size:14px;text-align:right;line-height:60px;}
.ak-jsch-event{ padding-left:55px; width:100%;}
.ak-jsch-event span{ position:relative;display:block; width:100%;height:30px;}
.ak-jsch-event span+span{border-top:#e7e9ea 1px solid;}
.ak-jsch-event .ak-jcalendar-td{ width:100%; padding-left:5px;}
.ak-jsch-day{ table-layout:fixed;}
.ak-jsch-day th,.ak-jsch-day td{ border-collapse:collapse; padding:5px; text-align:center; line-height:30px;}
.ak-jsch-day th{ font-weight:normal; font-size:12px;}
.ak-jsch-selected{ display:inline-block;width:30px;height:30px;color:#fff;border-radius:15px;background-color:#0072c6;}
.ak-jcalendar-minute.ak-jmin-25{bottom:1px;}
.ak-jcalendar-line.ak-jmin-25{ top:11px;}
.ak-jsch-red{}
@media(min-width:992px){.ak-jsch-day{width:80%; margin:0 auto;}}
@media(max-width:991px){.ak-jsch-day{width:100%;}}
/*schedule-detail css*/
.ak-jsch-timebox{ padding:0 10px;color:#909090;font-size:14px;line-height:28px; background-color:#f8f8f8;border-bottom:#e7e9ea 1px solid;}
.ak-jsch-timebox span+span{ margin-left:5px;}
.ak-jsch-cell{position:relative;height:60px;border-bottom:#e7e9ea 1px solid;}
.ak-jsch-cell-left{ position:absolute;padding:10px;width:120px;}
.ak-jsch-cell-right{ padding:10px 10px 10px 120px; width:100%;}
.ak-jsch-cell-left span{ display:block;font-size:14px;color:#2b2b2b;}
.ak-jsch-cell-left em{ display:block;font-size:14px;color:#c0c0c0;font-style:normal;}
.ak-jsch-point{ width:12px; height:12px; margin-top:4px; border-radius:6px; background-color:#c0392b;}
.ak-jsch-cell-right .ak-jsch-cell-title{ display:block; width:100%;font-size:14px;color:#2b2b2b;overflow:hidden;text-overflow:ellipsis; white-space:nowrap; cursor:pointer;}
.ak-jsch-cell-right p{ padding:0; margin:0; width:100%;font-size:14px;color:#c0c0c0;overflow:hidden;text-overflow:ellipsis; white-space:nowrap;}
.ak-mt15{ margin-top:15px;}
@media(max-width:768px){.ak-jsch-cell-left{ width:76px;}.ak-jsch-cell-right{ padding-left:76px;}.ak-jsch-cell-left span,.ak-jsch-cell-left em{ font-size:12px;margin-top:3px;}.ak-jsch-cell-left .ak-jsch-point{ margin-top:2px;}}
/*modal css*/
.ak-jsch-modal-row{ position:relative;padding-top:15px;background-color:#fff;/*border-top:#e1e1e1 1px solid; border-bottom:#e1e1e1 1px solid;*/}
.ak-jsch-pos{ position:absolute; /*width:36px;*/}
.ac-proname {margin-left:18px;}
.ak-jsch-modal-text{ /*padding-left:36px;*/ width:100%;font-size:14px;}
.ak-jsch-modal-item{padding:0;/*border-bottom:#e1e1e1 1px solid;*/}
.ak-jsch-modal-row.ak-jsch-padding{ padding:0; /*padding-left:15px;*/}
.ak-jsch-modal-row.ak-jsch-padding .ak-jsch-pos{ padding-top:15px;}
.ak-jsch-modal-row .ak-jsch-pos{text-align:center;}
.ak-jsch-pos .ak-jsch-point{ margin-left:auto; margin-right:auto;}
.ak-jsch-modal-text .ak-jsch-modal-item:last-child{ border:none;}
.ak-jsch-right-text .ak-sch-icon{ margin-left:10px;}
.ak-jsch-modal-row.ak-jsch-noborder{ border-top:none;}
.ak-jsch-modal-input{ width:100%;padding:3px 5px;border:1px solid #ccc;}
.ak-append-box.ak-jsch-timepicker{ width:224px;margin-bottom:0;}
.ak-jsch-modal-item .ak-jsch-item-left{ display:inline-block; width:75px;line-height:32px;text-align:right;}
.ak-jsch-item-right{ width:calc(100% - 100px); margin-left:10px;}
.ak-jsch-timepicker .input-group{ width:100%;}
.ak-jsch-timepicker +.ak-jsch-timepicker{ margin-right:10px;}
.ak-jsch-timepicker input.form-control{ border:none;}
.ak-jsch-timepicker .input-group-addon{ border-left:1px solid #bbb;}
.ak-jsch-timepicker .input-group-addon{ padding-left:8px;padding-right:9px;}
.ak-jsch-timepicker .ak-time-input{padding-left:8px;padding-right:9px;}
.ak-jsch-modal-item.ak-jsch-pt{ padding-top:10px;/*margin-left:20px;*/padding-bottom:10px;}
.ak-jwk-btn{padding:5px 14px;font-size:12px;color:#fff;background-color:#4684cf;cursor:pointer;}
.ak-jwk-btn:hover{color:#fff;background-color:#2F77CD;}
.ak-jsch-item-right .input {right: 0;}
@media(min-width:769px){.ak-jsch-modal-row{margin-left:-30px;margin-right:-30px;}.ak-jsch-modal-row.col01{margin-left:0;margin-right:0;}}
@media(max-width:768px){.ak-jsch-modal-row{margin-left:-15px;margin-right:-15px;}.ak-jsch-pos{ width:20px;}.ak-jsch-modal-text{ padding-left:24px;}}
@media(max-width:567px){.ak-jsch-timepicker +.ak-jsch-timepicker{ margin-right:0; margin-top:10px;}.ak-append-box.ak-jsch-timepicker{ width:90%;min-width:224px;}}
.ac-acaseedit-textarea {width:100%;height:100px;margin-top:12px;line-height:30px;line-height:25px;border:1px solid #ccc;-moz-border-radius:5px;}
.ak-jsch-modal-row.col01{padding-left:20px;}
.ak-zdol-trsmbtn {
width: 20px;
height: 20px;
display: inline-block;
float: left;
margin-right: 5px;
}
.ak-zdol-trsmbtn.icondelete-sm {
width: 26px;
background-position: -148px -56px;
margin-right: 10px;
}
.ak-zdol-trsmbtn.iconedit-sm {
width: 26px;
background-position: -111px -56px;
margin-right: 10px;
}
.ak-append-box{display: block;position: relative;border: 1px solid #ccc;width: 100%;}
.fa{cursor: pointer;}
.ak-time-icon{position: absolute;right: 1px;top: 0;width: 29px;height: 32px;line-height: 33px;text-align: center;border-left: 1px solid #bbb;}
.ak-time-input{width: 100%;height: 32px;padding: 6px 12px;font-weight: 400;border: none;}
.ak-zmemo-modal-tabnav {
border-bottom: none;
}
/*add by Arlene 2016-8-29*/
.ac-margin-tb20 {margin-top:20px;margin-bottom:20px;}
.ac-margin-tb15 {margin-top:15px;margin-bottom:12px;}
.ac-abtn {text-align:center;padding:3px 8px;border:none;border-radius:5px;color:#fff;font-size:12px;display: block;white-space:nowrap;overflow: hidden;text-overflow: ellipsis;}
.orange {background-color:#f90;}
.ac-abtn.orange:hover,.ac-btn-addcase:hover {background-color:#ef9002;color:#fff;}
.ac-abtn.blue:hover,.ac-btn-adduser:hover {background-color:#2a9dd6;color:#fff;}
.grey{background-color:#ccc}
.blue{background-color:#00bcf2;}
.green{background-color:#42c05d;}
.ac-abtn.green:hover {background-color:#3aaa52;color:#fff;}
.ac-abtn.blue:hover {background-color:#2a9dd6;color:#fff;}
.ac-abtn.red {background-color:#e30202;}
.ac-abtn.red:hover {background-color:#ce0808;color:#fff;}
.ac-aselect {margin-right:15px;/*padding:5px;*/border:1px solid #ccc;border-radius:5px;}
.ac-aselect.col01 {width:150px;}
.ac-aselect.col02 {width:100px;}
.case-next{height:60px;padding:0 10px;color:#555;line-height:50px;position:relative;}
.ac-asearch-box {width:200px;margin-right:15px;padding:4px 5px;border:1px solid #ccc;border-radius:5px;}
.ac-asearch-input {width:170px;border:none!important;background: transparent;}
.ac-search-icon {margin-top:5px;}
.ac-btn-addcase {padding:4px 10px;border-radius:5px;background-color:#f90;color:#fff;border:none;}
.ac-btn-adduser {padding:4px 10px;border-radius:5px;background-color: #00bcf2;color:#fff;border:none;}
.ac-aoffon-btn {display:inline-block;margin-left:10px;}
.ak-jsch-item-right.col02{margin-left:10px;width:calc(100% - 100px)}
.ac-acaseedit-state {margin-left:20px;}
.ac-acaseedit-select {width:100%;padding:8px;background:transparent;border:1px solid #ccc;}
.ac-acaseedit-input {padding:5px;background:transparent;border:1px solid #ccc;border-radius:5px;}
.ac-element-input {width: 250px;padding:5px;background:transparent;border:1px solid #ccc;border-radius:5px;}
.ac-keywordtext-input {width: 300px;padding:5px;background:transparent;border:1px solid #ccc;border-radius:5px;}
.ac-acase-desc {width:60px;}
.ac-acode-desc {width:300px;}
.modal-body {padding-top:0!important;}
@media screen and (-webkit-min-device-pixel-ratio:0) { /*safari and chrome*/
.ac-acaseedit-select,.ac-product-select {
height:32px;
line-height:32px;
}
.ac-aselect ,.ac-product-select{height:32px;line-height:32px;}
}
.ac-margint8 {margin-top:15px;}
select.ac-acaseedit-select::-moz-focus-inner { /*Remove button padding in FF*/
padding: 0;
}
.ac-aselect::-moz-focus-inner { /*Remove button padding in FF*/ height:32px;line-height:32px;}
@-moz-document url-prefix() { /* targets Firefox only */
.ac-aselect,.ac-product-select {height:32px;line-height:32px;}
}
@media screen\0 { /* IE Hacks: targets IE 8, 9 and 10 */
select.ac-acaseedit-select,.ac-product-select {
height:32px;
line-height:32px;
}
.ac-aselect ,.ac-product-select{height:32px;line-height:32px;}
}
.ac-ml10 {margin-left:10px;}
td.ac-alist-descp a {color:#00bcf2;}
td.ac-alist-descp a:hover {color:#2a9dd6;}
td.ac-alist-width-overflow {max-width:300px;white-space:nowrap;overflow:hidden;text-overflow: ellipsis;}
td.ac-alist-width-overflow-public {max-width:200px;white-space:nowrap;overflow:hidden;text-overflow: ellipsis;}
.ac-product-select {width:200px;height:32px;margin:10px 20px auto auto;}
div.ac-interlist-width-overflow {max-width:200px;white-space:nowrap;overflow:hidden;text-overflow: ellipsis;}
.panel0{padding-top: 0px;padding-bottom: 0px;}
/*leftnavbar*/
.ak-aper-navicon {width:40px;height:40px;}
.list-group-item.a-listitem {height:60px;}
.ak-aper-navicon span {dispaly:block;height:40px;}
.ak-zper-chaticon{width:20px;height:20px;background:url(../images/chat01.png) no-repeat 0 0;float:right;margin-top:20px;margin-right:20px;}
.ak-jsch-jia {
margin-right:0;
margin-top:10px ;
display: inline-block;
width: 36px;
height: 36px;
background: url(../images/ak-common.png) -480px -180px no-repeat;
cursor: pointer;
}
.gn-menu-main { height: 56px; }
.ak-min-fullwidth-modal .close.close-back{width: 25px;height: 25px;background: url(../images/zkonw-back.png) no-repeat center center;opacity: 1;color: transparent;margin-top: 4px;outline: medium none;float: left;margin:0;}
/*.ac-acedit-addlinebtn {margin-left:30px;}*/
.ak-acedit-tablelist {margin:15px 30px;}
.ac-addtips{display:none;position:absolute;left:40%;top:5px;width:200px;height:40px;margin-left:-100px;border-radius:5px;text-align:center;line-height:40px;font-size:14px;color: #ffffff;}
.ac-aset-table {width:700px;margin:0 auto;}
.ac-aset-table td.col01 {width:80px;text-align:right;margin-right:10px;}
.ak-jsch-modal-text.col01{padding-left:15px;}
.sky-form.col01 .toggle i {top:8px;left:0;}
.ak-jsch-item-right.col01 {width:100%;}
.ac-apro-span {display:block;margin-top:12px;}
.search-width{width: 300px !important;}
.ac-amargin-r10 {margin-right:10px;}
.ac-amargin-tb20 {margin-top:20px;margin-bottom:20px;}
.ac-aelement-table th {padding:10px 5px!important;font-size:12px;}
.ac-aelement-table td{padding:10px 5px!important;}
.table-hover tr:hover {background-color:#d4edfe!important;}
.ui-autocomplete {
max-height: 200px;
overflow-y: auto;
/* 防止水平滚动条 */
overflow-x: hidden;
padding: 10px;
}
/* IE 6 不支持 max-height
* 我们使用 height 代替,但是这会强制菜单总是显示为那个高度
*/
* html .ui-autocomplete {
height: 100px;
}
/*2016-12-1 add*/
.ke-icon {display:inline-block;width:25px;height:25px;background-image: url("../images/icon.png");background-repeat: no-repeat;background-size:96px 48px;}
.ke-icon.upicon {background-position: 0 0;}
.ke-icon.downicon {background-position: -25px 0;}
.ke-icon.deleteicon {background-position: -50px 0;}
.ke-icon.copyicon {background-position: -75px 0;}
a:hover .ke-icon.upicon {background-position: 0 -25px;}
a:hover .ke-icon.downicon {background-position: -25px -25px;}
a:hover .ke-icon.deleteicon {background-position: -50px -25px;}
a:hover .ke-icon.copyicon {background-position: -75px -25px;}
a.ke-ablock {display:inline-block;width:25px;height:25px;line-height: 25px; cursor: pointer}
.glyphicon-play-circle:before{
color: #00B83F;
}
.glyphicon-edit:before{
color: #0AA5DF;
}
.glyphicon-trash:before{
color: red;
}
.glyphicon-eye-open:before{
color: #0AA5DF;
}
.glyphicon-eye-close:before{
color: #ec971f;
}
.ac-margint10 {margin-top:10px;}
.ac-paddingt0 {padding-top:0px !important;}
.ac-margin110 {margin-left:10px;}
.status_200 {background-color: #5cb85c}
.status_201 {background-color: #5cb85c}
.status_202 {background-color: #5cb85c}
.status_203 {background-color: #5cb85c}
.status_304 {background-color: #5bc0de}
.status_400 {background-color: #d9534f}
.status_401 {background-color: #d9534f}
.status_402 {background-color: #d9534f}
.status_403 {background-color: #d9534f}
.status_404 {background-color: #d9534f}
.status_500 {background-color: #d9534f}
.status_501 {background-color: #d9534f}
================================================
FILE: automatic/static/css/bootstrap-theme.css
================================================
/*!
* Bootstrap v3.3.5 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
.btn-default,
.btn-primary,
.btn-success,
.btn-info,
.btn-warning,
.btn-danger {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
}
.btn-default:active,
.btn-primary:active,
.btn-success:active,
.btn-info:active,
.btn-warning:active,
.btn-danger:active,
.btn-default.active,
.btn-primary.active,
.btn-success.active,
.btn-info.active,
.btn-warning.active,
.btn-danger.active {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-default.disabled,
.btn-primary.disabled,
.btn-success.disabled,
.btn-info.disabled,
.btn-warning.disabled,
.btn-danger.disabled,
.btn-default[disabled],
.btn-primary[disabled],
.btn-success[disabled],
.btn-info[disabled],
.btn-warning[disabled],
.btn-danger[disabled],
fieldset[disabled] .btn-default,
fieldset[disabled] .btn-primary,
fieldset[disabled] .btn-success,
fieldset[disabled] .btn-info,
fieldset[disabled] .btn-warning,
fieldset[disabled] .btn-danger {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-default .badge,
.btn-primary .badge,
.btn-success .badge,
.btn-info .badge,
.btn-warning .badge,
.btn-danger .badge {
text-shadow: none;
}
.btn:active,
.btn.active {
background-image: none;
}
.btn-default {
text-shadow: 0 1px 0 #fff;
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #dbdbdb;
border-color: #ccc;
}
.btn-default:hover,
.btn-default:focus {
background-color: #e0e0e0;
background-position: 0 -15px;
}
.btn-default:active,
.btn-default.active {
background-color: #e0e0e0;
border-color: #dbdbdb;
}
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
background-color: #e0e0e0;
background-image: none;
}
.btn-primary {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #245580;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #265a88;
background-position: 0 -15px;
}
.btn-primary:active,
.btn-primary.active {
background-color: #265a88;
border-color: #245580;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: #265a88;
background-image: none;
}
.btn-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #3e8f3e;
}
.btn-success:hover,
.btn-success:focus {
background-color: #419641;
background-position: 0 -15px;
}
.btn-success:active,
.btn-success.active {
background-color: #419641;
border-color: #3e8f3e;
}
.btn-success.disabled,
.btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
background-color: #419641;
background-image: none;
}
.btn-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #28a4c9;
}
.btn-info:hover,
.btn-info:focus {
background-color: #2aabd2;
background-position: 0 -15px;
}
.btn-info:active,
.btn-info.active {
background-color: #2aabd2;
border-color: #28a4c9;
}
.btn-info.disabled,
.btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
background-color: #2aabd2;
background-image: none;
}
.btn-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #e38d13;
}
.btn-warning:hover,
.btn-warning:focus {
background-color: #eb9316;
background-position: 0 -15px;
}
.btn-warning:active,
.btn-warning.active {
background-color: #eb9316;
border-color: #e38d13;
}
.btn-warning.disabled,
.btn-warning[disabled],
fieldset[disabled] .btn-warning,
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus,
.btn-warning.disabled:active,
.btn-warning[disabled]:active,
fieldset[disabled] .btn-warning:active,
.btn-warning.disabled.active,
.btn-warning[disabled].active,
fieldset[disabled] .btn-warning.active {
background-color: #eb9316;
background-image: none;
}
.btn-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #b92c28;
}
.btn-danger:hover,
.btn-danger:focus {
background-color: #c12e2a;
background-position: 0 -15px;
}
.btn-danger:active,
.btn-danger.active {
background-color: #c12e2a;
border-color: #b92c28;
}
.btn-danger.disabled,
.btn-danger[disabled],
fieldset[disabled] .btn-danger,
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus,
.btn-danger.disabled:active,
.btn-danger[disabled]:active,
fieldset[disabled] .btn-danger:active,
.btn-danger.disabled.active,
.btn-danger[disabled].active,
fieldset[disabled] .btn-danger.active {
background-color: #c12e2a;
background-image: none;
}
.thumbnail,
.img-thumbnail {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
background-color: #e8e8e8;
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
background-color: #2e6da4;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.navbar-default {
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
}
.navbar-brand,
.navbar-nav > li > a {
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
}
.navbar-inverse {
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-radius: 4px;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
}
.navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav > li > a {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
}
.navbar-static-top,
.navbar-fixed-top,
.navbar-fixed-bottom {
border-radius: 0;
}
@media (max-width: 767px) {
.navbar .navbar-nav .open .dropdown-menu > .active > a,
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
}
.alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
}
.alert-success {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
background-repeat: repeat-x;
border-color: #b2dba1;
}
.alert-info {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #9acfea;
}
.alert-warning {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
background-repeat: repeat-x;
border-color: #f5e79e;
}
.alert-danger {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
background-repeat: repeat-x;
border-color: #dca7a7;
}
.progress {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-striped {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.list-group {
border-radius: 4px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
background-repeat: repeat-x;
border-color: #2b669a;
}
.list-group-item.active .badge,
.list-group-item.active:hover .badge,
.list-group-item.active:focus .badge {
text-shadow: none;
}
.panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}
.panel-default > .panel-heading {
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
}
.panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.panel-success > .panel-heading {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
background-repeat: repeat-x;
}
.panel-info > .panel-heading {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
background-repeat: repeat-x;
}
.panel-warning > .panel-heading {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
background-repeat: repeat-x;
}
.panel-danger > .panel-heading {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
background-repeat: repeat-x;
}
.well {
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
border-color: #dcdcdc;
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
}
/*# sourceMappingURL=bootstrap-theme.css.map */
================================================
FILE: automatic/static/css/bootstrap.css
================================================
/*!
* Bootstrap v3.3.5 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
h1 {
margin: .67em 0;
font-size: 2em;
}
mark {
color: #000;
background: #ff0;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sup {
top: -.5em;
}
sub {
bottom: -.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 1em 40px;
}
hr {
height: 0;
-webkit-box-sizing: content-box;
gitextract_402wqmeg/ ├── Dockerfile ├── LICENSE ├── README.md ├── auto_auth/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations/ │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── automatic/ │ ├── __init__.py │ ├── asgi.py │ ├── element/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── forms.py │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── keywords/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── fixtures/ │ │ │ └── initial_data.json │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── management/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── settings/ │ │ ├── __init__.py │ │ └── common.py │ ├── signals.py │ ├── static/ │ │ ├── css/ │ │ │ ├── ak-base-style.css │ │ │ ├── ak-schedule.css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrapValidator.css │ │ │ ├── font-awesome/ │ │ │ │ ├── css/ │ │ │ │ │ ├── font-awesome-ie7.css │ │ │ │ │ └── font-awesome.css │ │ │ │ ├── font/ │ │ │ │ │ └── FontAwesome.otf │ │ │ │ ├── fonts/ │ │ │ │ │ └── FontAwesome.otf │ │ │ │ ├── less/ │ │ │ │ │ ├── animated.less │ │ │ │ │ ├── bootstrap.less │ │ │ │ │ ├── bordered-pulled.less │ │ │ │ │ ├── core.less │ │ │ │ │ ├── extras.less │ │ │ │ │ ├── fixed-width.less │ │ │ │ │ ├── font-awesome-ie7.less │ │ │ │ │ ├── font-awesome.less │ │ │ │ │ ├── icons.less │ │ │ │ │ ├── larger.less │ │ │ │ │ ├── list.less │ │ │ │ │ ├── mixins.less │ │ │ │ │ ├── path.less │ │ │ │ │ ├── rotated-flipped.less │ │ │ │ │ ├── stacked.less │ │ │ │ │ └── variables.less │ │ │ │ └── scss/ │ │ │ │ ├── _animated.scss │ │ │ │ ├── _bootstrap.scss │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ ├── _core.scss │ │ │ │ ├── _extras.scss │ │ │ │ ├── _fixed-width.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _larger.scss │ │ │ │ ├── _list.scss │ │ │ │ ├── _mixins.scss │ │ │ │ ├── _path.scss │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ ├── _stacked.scss │ │ │ │ ├── _variables.scss │ │ │ │ ├── font-awesome-ie7.scss │ │ │ │ └── font-awesome.scss │ │ │ ├── font-awesome.css │ │ │ ├── jquery-ui.css │ │ │ ├── login-app.css │ │ │ ├── login-vendor.css │ │ │ ├── page-v3/ │ │ │ │ ├── ak-master-page-v3.css │ │ │ │ └── ak-master-page-v3style.css │ │ │ └── wheelmenu.css │ │ ├── js/ │ │ │ ├── automagic.js │ │ │ ├── back-to-top.js │ │ │ ├── bootstrapValidator.js │ │ │ ├── casemanage.js │ │ │ ├── common.js │ │ │ ├── jquery-ui.js │ │ │ ├── jquery.wheelmenu.js │ │ │ ├── keyword.js │ │ │ └── taskmanage.js │ │ ├── muti_select/ │ │ │ ├── css/ │ │ │ │ ├── multi.css │ │ │ │ └── style.css │ │ │ └── src/ │ │ │ └── MultiSelectDropList.js │ │ └── zTree_v3/ │ │ ├── css/ │ │ │ ├── awesomeStyle/ │ │ │ │ ├── awesome.css │ │ │ │ ├── awesome.less │ │ │ │ └── fa.less │ │ │ ├── demo.css │ │ │ ├── metroStyle/ │ │ │ │ └── metroStyle.css │ │ │ └── zTreeStyle/ │ │ │ └── zTreeStyle.css │ │ └── js/ │ │ ├── jquery.ztree.all.js │ │ ├── jquery.ztree.core.js │ │ ├── jquery.ztree.excheck.js │ │ ├── jquery.ztree.exedit.js │ │ └── jquery.ztree.exhide.js │ ├── templates/ │ │ ├── 404.html │ │ ├── 500.html │ │ ├── base.html │ │ ├── comingsoon.html │ │ ├── element/ │ │ │ └── element.html │ │ ├── frame.html │ │ ├── index.html │ │ ├── keywords/ │ │ │ └── keyword.html │ │ ├── management/ │ │ │ ├── moduleadd.html │ │ │ ├── moduleview.html │ │ │ ├── productadd.html │ │ │ ├── productlist.html │ │ │ ├── productview.html │ │ │ ├── projectadd.html │ │ │ ├── projectlist.html │ │ │ ├── projectview.html │ │ │ └── syslog.html │ │ ├── nav.html │ │ ├── oauth/ │ │ │ └── userlist.html │ │ ├── registration/ │ │ │ └── login.html │ │ ├── testcase/ │ │ │ ├── caseadd.html │ │ │ ├── casecopy.html │ │ │ ├── caseedit.html │ │ │ ├── caselist.html │ │ │ └── caseview.html │ │ ├── testtask/ │ │ │ ├── taskadd.html │ │ │ ├── taskedit.html │ │ │ └── tasklist.html │ │ └── webinterface/ │ │ └── webinterface.html │ ├── testcase/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── forms.py │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── testtask/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── urls.py │ ├── webinterface/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations/ │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ └── wsgi.py ├── docker-compose.yml ├── init.sh ├── insertkeyword.sql ├── manage.py ├── requirements/ │ ├── base.txt │ └── seleniumreq.txt ├── seleniumkeyword/ │ ├── AddCase.py │ ├── Base.py │ ├── CustomKeyword.py │ ├── HTMLTestRunner.py │ ├── README.MD │ ├── RestApiUtil.py │ ├── SimulatorUtil.py │ ├── TestSuite.py │ ├── __init__.py │ ├── data/ │ │ └── readme.md │ ├── mwupgrade.py │ ├── popautomagic.py │ ├── result/ │ │ └── highcharts.js │ ├── sendlog/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── guitest.py │ │ ├── mysetup.py │ │ ├── randip.py │ │ ├── randomip.py │ │ ├── send.config │ │ ├── sendingdata.py │ │ ├── syslogc.py │ │ ├── tcpsendingsyslog.py │ │ ├── tcpsendtest.py │ │ ├── udpsendingsyslog.py │ │ └── weighted_choice.py │ ├── settings.py │ ├── testrail.py │ └── testraildemo.py └── start.py
SYMBOL INDEX (438 symbols across 66 files)
FILE: auto_auth/apps.py
class AutoAuthConfig (line 4) | class AutoAuthConfig(AppConfig):
FILE: auto_auth/forms.py
class RegistrationForm (line 9) | class RegistrationForm(UserCreationForm):
class Meta (line 12) | class Meta:
method clean_email (line 16) | def clean_email(self):
method save (line 25) | def save(self, commit=True):
method set_activation_key (line 39) | def set_activation_key(self):
FILE: auto_auth/migrations/0001_initial.py
class Migration (line 11) | class Migration(migrations.Migration):
FILE: auto_auth/models.py
class UserActivationKey (line 10) | class UserActivationKey(models.Model):
method set_random_key_for_user (line 16) | def set_random_key_for_user(cls, user, force=False):
class MyUserManager (line 29) | class MyUserManager(BaseUserManager):
method create_user (line 35) | def create_user(self, username, email, password):
method create_superuser (line 48) | def create_superuser(self, username, email, password):
class User (line 59) | class User(AbstractUser):
method get_full_name (line 72) | def get_full_name(self):
method get_short_name (line 76) | def get_short_name(self):
method __unicode__ (line 80) | def __unicode__(self): # __unicode__ on Python 2
method has_perm (line 83) | def has_perm(self, perm, obj=None):
method has_module_perms (line 88) | def has_module_perms(self, app_label):
FILE: auto_auth/views.py
class LoginViewWithCustomTemplate (line 27) | class LoginViewWithCustomTemplate(views.LoginView):
method get_template_names (line 28) | def get_template_names(self):
function index (line 33) | def index(request):
function register (line 37) | def register(request):
function confirm (line 98) | def confirm(request, activation_key):
function profile (line 131) | def profile(request, username):
function verify (line 137) | def verify(request, query_dict):
function login_page (line 147) | def login_page(request):
function _logout (line 153) | def _logout(request):
function add_user (line 159) | def add_user(request):
function update_user (line 214) | def update_user(request):
function del_user (line 266) | def del_user(request,id):
function set_edit_user (line 274) | def set_edit_user(request):
class UserListIndex (line 294) | class UserListIndex(ListView):
method get_queryset (line 303) | def get_queryset(self):
method get_context_data (line 312) | def get_context_data(self, **kwargs):
FILE: automatic/element/admin.py
class ElementAdmin (line 8) | class ElementAdmin(admin.ModelAdmin):
FILE: automatic/element/apps.py
class ElementConfig (line 4) | class ElementConfig(AppConfig):
FILE: automatic/element/forms.py
class FormElement (line 12) | class FormElement(forms.ModelForm):
class Meta (line 13) | class Meta:
FILE: automatic/element/migrations/0001_initial.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: automatic/element/models.py
class Element (line 11) | class Element(models.Model):
method __unicode__ (line 32) | def __unicode__(self):
FILE: automatic/element/views.py
class ElementListIndex (line 25) | class ElementListIndex(ListView):
method get_queryset (line 33) | def get_queryset(self):
method get_context_data (line 51) | def get_context_data(self, **kwargs):
function add_element (line 62) | def add_element(request):
function update_element (line 83) | def update_element(request):
function del_element (line 109) | def del_element(request, id):
function get_element (line 116) | def get_element(request):
function set_edit_element (line 132) | def set_edit_element(request):
FILE: automatic/keywords/admin.py
class KeywordAdmin (line 8) | class KeywordAdmin(admin.ModelAdmin):
FILE: automatic/keywords/apps.py
class KeywordsConfig (line 4) | class KeywordsConfig(AppConfig):
FILE: automatic/keywords/migrations/0001_initial.py
class Migration (line 6) | class Migration(migrations.Migration):
FILE: automatic/keywords/models.py
class Keyword (line 11) | class Keyword(models.Model):
method __unicode__ (line 20) | def __unicode__(self):
class Meta (line 23) | class Meta:
FILE: automatic/keywords/views.py
class KeyWordListIndex (line 24) | class KeyWordListIndex(ListView):
method get_queryset (line 32) | def get_queryset(self):
method get_context_data (line 40) | def get_context_data(self, **kwargs):
function add_keyword (line 49) | def add_keyword(request):
function update_keyword (line 68) | def update_keyword(request):
function del_keyword (line 84) | def del_keyword(request, id):
function get_keyword (line 91) | def get_keyword(request):
function set_edit_keyword (line 106) | def set_edit_keyword(request):
FILE: automatic/management/admin.py
class ProductAdmin (line 8) | class ProductAdmin(admin.ModelAdmin):
class ProjectAdmin (line 13) | class ProjectAdmin(admin.ModelAdmin):
class ModuleAdmin (line 18) | class ModuleAdmin(admin.ModelAdmin):
FILE: automatic/management/apps.py
class ManagementConfig (line 4) | class ManagementConfig(AppConfig):
FILE: automatic/management/migrations/0001_initial.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: automatic/management/models.py
class Product (line 15) | class Product(models.Model):
method __unicode__ (line 26) | def __unicode__(self):
method save (line 29) | def save(self, *args, **kwargs):
class Meta (line 36) | class Meta:
class Project (line 40) | class Project(models.Model):
method __unicode__ (line 52) | def __unicode__(self):
class Meta (line 55) | class Meta:
class Module (line 59) | class Module(models.Model):
method __unicode__ (line 69) | def __unicode__(self):
class Meta (line 72) | class Meta:
class UserAndProduct (line 75) | class UserAndProduct(models.Model):
FILE: automatic/management/views.py
function add_product (line 21) | def add_product(request):
function update_product (line 47) | def update_product(request):
function del_product (line 74) | def del_product(request,id):
function view_product (line 81) | def view_product(request, id):
class ProductListIndex (line 97) | class ProductListIndex(ListView):
method get_queryset (line 105) | def get_queryset(self):
method get_context_data (line 117) | def get_context_data(self, **kwargs):
class ProjectListIndex (line 125) | class ProjectListIndex(ListView):
method get_queryset (line 133) | def get_queryset(self):
method get_context_data (line 147) | def get_context_data(self, **kwargs):
function add_project (line 158) | def add_project(request):
function update_project (line 191) | def update_project(request):
function del_project (line 220) | def del_project(request,id):
function view_project (line 229) | def view_project(request, id):
class ModuleListIndex (line 241) | class ModuleListIndex(ListView):
method get_queryset (line 249) | def get_queryset(self):
method get_context_data (line 263) | def get_context_data(self, **kwargs):
function add_module (line 272) | def add_module(request):
function update_module (line 300) | def update_module(request):
function del_module (line 325) | def del_module(request, id):
function get_project (line 332) | def get_project(request):
function get_module (line 345) | def get_module(request):
function get_connected_user (line 359) | def get_connected_user(request):
function get_module_list (line 375) | def get_module_list(request):
function set_edit_product (line 404) | def set_edit_product(request):
function set_edit_project (line 417) | def set_edit_project(request):
function set_edit_module (line 431) | def set_edit_module(request):
function product_user (line 446) | def product_user(request):
function page_syslog (line 460) | def page_syslog(request):
function comingsoon (line 464) | def comingsoon(request):
FILE: automatic/static/js/automagic.js
function getUrlParam (line 8) | function getUrlParam(name) {
function setproductValue (line 586) | function setproductValue(id) {
function setprojectValue (line 615) | function setprojectValue(id) {
function setmoduleValue (line 645) | function setmoduleValue(id) {
function setuserValue (line 674) | function setuserValue(id) {
function setelementValue (line 721) | function setelementValue(id) {
function runcase (line 936) | function runcase(id) {
function runtask (line 960) | function runtask(id) {
function viewdebuginfo (line 983) | function viewdebuginfo(x) {
function up (line 995) | function up(obj) {
function down (line 1002) | function down(obj) {
function goback (line 1010) | function goback() {
FILE: automatic/static/js/casemanage.js
function case_step_addtr (line 124) | function case_step_addtr() {
function case_step_copytr (line 171) | function case_step_copytr(obj) {
function deltr (line 230) | function deltr(index) {
FILE: automatic/static/js/common.js
function localStorageSupport (line 25) | function localStorageSupport() {
FILE: automatic/static/js/jquery-ui.js
function _super (line 128) | function _super() {
function _superApply (line 132) | function _superApply( args ) {
function processClassString (line 512) | function processClassString( classes, checkOption ) {
function handlerProxy (line 595) | function handlerProxy() {
function handlerProxy (line 639) | function handlerProxy() {
function getOffsets (line 775) | function getOffsets( offsets, width, height ) {
function parseCss (line 782) | function parseCss( element, property ) {
function getDimensions (line 786) | function getDimensions( elem ) {
function clamp (line 1482) | function clamp( value, prop, allowEmpty ) {
function stringParse (line 1509) | function stringParse( string ) {
function hue2rgb (line 1763) | function hue2rgb( p, q, h ) {
function getElementStyles (line 2037) | function getElementStyles( elem ) {
function styleDifference (line 2065) | function styleDifference( oldStyle, newStyle ) {
function _normalizeArguments (line 2558) | function _normalizeArguments( effect, options, speed, callback ) {
function standardAnimationOption (line 2610) | function standardAnimationOption( option ) {
function run (line 2687) | function run( next ) {
function parseClip (line 2835) | function parseClip( str, element ) {
function childComplete (line 3219) | function childComplete() {
function animComplete (line 3269) | function animComplete() {
function visible (line 3929) | function visible( element ) {
function reduce (line 4057) | function reduce( elem, size, border, margin ) {
function datepicker_getZindex (line 7189) | function datepicker_getZindex( elem ) {
function Datepicker (line 7218) | function Datepicker() {
function datepicker_bindHover (line 9184) | function datepicker_bindHover( dpDiv ) {
function datepicker_handleMouseover (line 9198) | function datepicker_handleMouseover() {
function datepicker_extendRemove (line 9212) | function datepicker_extendRemove( target, props ) {
function checkFocus (line 12247) | function checkFocus() {
function filteredUi (line 12454) | function filteredUi( ui ) {
function filteredUi (line 12502) | function filteredUi( ui ) {
function isOverAxis (line 13099) | function isOverAxis( x, reference, size ) {
function addItems (line 15923) | function addItems() {
function delayEvent (line 16657) | function delayEvent( type, instance, container ) {
function spinnerModifer (line 16757) | function spinnerModifer( fn ) {
function checkFocus (line 16888) | function checkFocus() {
function constrain (line 17539) | function constrain() {
function complete (line 17926) | function complete() {
function show (line 17931) | function show() {
function position (line 18483) | function position( event ) {
FILE: automatic/static/js/jquery.wheelmenu.js
function predefineAngle (line 183) | function predefineAngle (settings) {
function predefineSpeed (line 229) | function predefineSpeed(settings) {
FILE: automatic/static/js/keyword.js
function setkeywordValue (line 6) | function setkeywordValue(id){
FILE: automatic/static/js/taskmanage.js
function sortNumber (line 225) | function sortNumber(a,b){
function setTreeValue (line 230) | function setTreeValue(caselist){
function addtr (line 302) | function addtr() {
function deltr (line 320) | function deltr(index) {
FILE: automatic/static/zTree_v3/js/jquery.ztree.all.js
function addCallback (line 1622) | function addCallback() {
function showNodeFocus (line 1673) | function showNodeFocus() {
function showNodeFocus (line 1781) | function showNodeFocus() {
function copyCallback (line 2644) | function copyCallback() {
function moveCallback (line 2674) | function moveCallback() {
function _docMouseMove (line 2770) | function _docMouseMove(event) {
function _docMouseUp (line 3067) | function _docMouseUp(event) {
function _docSelect (line 3163) | function _docSelect() {
FILE: automatic/static/zTree_v3/js/jquery.ztree.core.js
function addCallback (line 1621) | function addCallback() {
function showNodeFocus (line 1672) | function showNodeFocus() {
function showNodeFocus (line 1780) | function showNodeFocus() {
FILE: automatic/static/zTree_v3/js/jquery.ztree.exedit.js
function copyCallback (line 194) | function copyCallback() {
function moveCallback (line 224) | function moveCallback() {
function _docMouseMove (line 320) | function _docMouseMove(event) {
function _docMouseUp (line 617) | function _docMouseUp(event) {
function _docSelect (line 713) | function _docSelect() {
FILE: automatic/testcase/admin.py
class CaseAdmin (line 8) | class CaseAdmin(admin.ModelAdmin):
class StepAdmin (line 13) | class StepAdmin(admin.ModelAdmin):
FILE: automatic/testcase/apps.py
class TestcaseConfig (line 4) | class TestcaseConfig(AppConfig):
FILE: automatic/testcase/forms.py
class FormCase (line 11) | class FormCase(forms.ModelForm):
class Meta (line 12) | class Meta:
class FormStep (line 17) | class FormStep(forms.ModelForm):
class Meta (line 18) | class Meta:
FILE: automatic/testcase/migrations/0001_initial.py
class Migration (line 9) | class Migration(migrations.Migration):
FILE: automatic/testcase/models.py
class Case (line 15) | class Case(models.Model):
method __unicode__ (line 29) | def __unicode__(self):
class Step (line 45) | class Step(models.Model):
method __unicode__ (line 57) | def __unicode__(self):
FILE: automatic/testcase/views.py
function add_case (line 27) | def add_case(request):
function update_case (line 84) | def update_case(request, id):
function copy_case (line 141) | def copy_case(request, id):
function del_case (line 198) | def del_case(request,id):
function del_step (line 205) | def del_step(request, id):
function view_case (line 214) | def view_case(request, id):
class CaseListIndex (line 220) | class CaseListIndex(ListView):
method get_queryset (line 229) | def get_queryset(self):
method get_context_data (line 253) | def get_context_data(self, **kwargs):
function get_caselist (line 265) | def get_caselist(request):
function run_case (line 278) | def run_case(request):
FILE: automatic/testtask/admin.py
class KeywordAdmin (line 8) | class KeywordAdmin(admin.ModelAdmin):
class CodelistAdmin (line 13) | class CodelistAdmin(admin.ModelAdmin):
class TaskhistoryAdmin (line 18) | class TaskhistoryAdmin(admin.ModelAdmin):
FILE: automatic/testtask/apps.py
class TesttaskConfig (line 4) | class TesttaskConfig(AppConfig):
FILE: automatic/testtask/migrations/0001_initial.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: automatic/testtask/models.py
class Task (line 12) | class Task(models.Model):
method __unicode__ (line 36) | def __unicode__(self):
class Codelist (line 39) | class Codelist(models.Model):
method __unicode__ (line 49) | def __unicode__(self):
class Taskhistory (line 52) | class Taskhistory(models.Model):
method __unicode__ (line 67) | def __unicode__(self):
FILE: automatic/testtask/views.py
function duration_change (line 25) | def duration_change(num):
function timeStamp (line 43) | def timeStamp(timastamp):
function testreport (line 50) | def testreport(path):
class TaskListIndex (line 55) | class TaskListIndex(ListView):
method get_queryset (line 64) | def get_queryset(self):
method get_context_data (line 86) | def get_context_data(self, **kwargs):
function add_task (line 97) | def add_task(request):
function update_task (line 136) | def update_task(request,id):
function del_task (line 179) | def del_task(request,id):
function run_task (line 186) | def run_task(request):
function set_tree_task (line 223) | def set_tree_task(request):
function get_task_history (line 231) | def get_task_history(request):
FILE: automatic/webinterface/admin.py
class WebinterfaceAdmin (line 6) | class WebinterfaceAdmin(admin.ModelAdmin):
method save_model (line 10) | def save_model(self, request, obj, form, change):
method get_search_results (line 19) | def get_search_results(self, request, queryset, search_term):
class WebresponseAdmin (line 28) | class WebresponseAdmin(admin.ModelAdmin):
FILE: automatic/webinterface/apps.py
class WebinterfaceConfig (line 6) | class WebinterfaceConfig(AppConfig):
FILE: automatic/webinterface/migrations/0001_initial.py
class Migration (line 7) | class Migration(migrations.Migration):
FILE: automatic/webinterface/models.py
class Webinterface (line 13) | class Webinterface(models.Model):
method __unicode__ (line 47) | def __unicode__(self):
class Webresponse (line 51) | class Webresponse(models.Model):
method __unicode__ (line 64) | def __unicode__(self):
FILE: automatic/webinterface/views.py
class WebinterfaceListIndex (line 11) | class WebinterfaceListIndex(ListView):
method get_queryset (line 20) | def get_queryset(self):
method get_context_data (line 41) | def get_context_data(self, **kwargs):
function get_response (line 55) | def get_response(request):
FILE: manage.py
function main (line 7) | def main():
FILE: seleniumkeyword/AddCase.py
function get_args (line 8) | def get_args():
function add_cass (line 22) | def add_cass(user, password, section_id, case_data):
class MyPySql (line 49) | class MyPySql(object):
method __init__ (line 50) | def __init__(self):
method set_conn (line 55) | def set_conn(self):
method execute (line 59) | def execute(self, sql):
method fetchall (line 67) | def fetchall(self):
method commit (line 70) | def commit(self):
method close (line 73) | def close(self):
FILE: seleniumkeyword/Base.py
class Action (line 18) | class Action(object):
method __init__ (line 21) | def __init__(self):
method __del__ (line 28) | def __del__(self):
method add_action (line 34) | def add_action(cls, keyword):
method highlightElement (line 44) | def highlightElement(self, element):
method notes (line 52) | def notes(self, text):
method show_note (line 69) | def show_note(self,stext):
method send_keys (line 75) | def send_keys(self, loc, value):
method find_element (line 83) | def find_element(self, loc):
method find_elements (line 96) | def find_elements(self, loc):
method isElementExsit (line 105) | def isElementExsit(self, loc):
method find_elements_i (line 116) | def find_elements_i(self, index, loc):
method saveScreenshot (line 125) | def saveScreenshot(self, name):
method savePngName (line 134) | def savePngName(self, name):
method save_runing_log (line 154) | def save_runing_log(self, text):
method saveVideoName (line 176) | def saveVideoName(self, name):
method saveTime (line 196) | def saveTime(self):
function action_openBrowser (line 210) | def action_openBrowser(action_object, step_desc, value, loc):
function action_InputText (line 274) | def action_InputText(action_object, step_desc, value, loc):
function action_uploadfile (line 298) | def action_uploadfile(action_object, step_desc, value, loc):
function action_jscript (line 312) | def action_jscript(action_object, step_desc, value, loc):
function action_moveScroll (line 328) | def action_moveScroll(action_object, step_desc, value, loc):
function action_moveScroll (line 345) | def action_moveScroll(action_object, step_desc, value, loc):
function action_timestamp (line 362) | def action_timestamp(action_object, step_desc, value, loc):
function action_submit (line 386) | def action_submit(action_object, step_desc, value, loc):
function action_refresh (line 400) | def action_refresh(action_object, step_desc, value, loc):
function action_closeBrowser (line 412) | def action_closeBrowser(action_object, step_desc, value, loc):
function action_navigate (line 426) | def action_navigate(action_object, step_desc, value, loc):
function action_click (line 451) | def action_click(action_object, step_desc, value, loc):
function action_clicks (line 465) | def action_clicks(action_object, step_desc, value, loc):
function action_checkclick (line 479) | def action_checkclick(action_object, step_desc, value, loc):
function action_select (line 495) | def action_select(action_object, step_desc, value,loc):
function action_selectText (line 508) | def action_selectText(action_object, step_desc, value,loc):
function action_swichframe (line 522) | def action_swichframe(action_object, step_desc, value, loc):
function action_defaultframe (line 536) | def action_defaultframe(action_object, step_desc, value, loc):
function action_assert (line 550) | def action_assert(action_object, step_desc, value, loc):
function action_valueassert (line 559) | def action_valueassert(action_object, step_desc, value, loc):
function action_notassert (line 576) | def action_notassert(action_object, step_desc, value, loc):
function action_assertTrue (line 587) | def action_assertTrue(action_object, step_desc, value, loc):
function action_assertFalse (line 606) | def action_assertFalse(action_object, step_desc, value, loc):
function action_assertUrl (line 625) | def action_assertUrl(action_object, step_desc, value, loc):
function action_isDisplayed (line 644) | def action_isDisplayed(action_object, step_desc, value, loc):
function action_isEnabled (line 662) | def action_isEnabled(action_object, step_desc, value, loc):
function action_sleep (line 686) | def action_sleep(action_object, step_desc, value, loc):
function sshclient_execmd (line 699) | def sshclient_execmd(action_object, step_desc, value, loc):
function exists_file (line 735) | def exists_file(action_object, step_desc, value, loc):
function action_udpsend (line 761) | def action_udpsend(action_object,step_desc, value, loc):
function sshclient_dpiblacklist (line 785) | def sshclient_dpiblacklist(action_object, step_desc, value, loc):
function action_login (line 832) | def action_login(action_object, step_desc, value, loc):
function action_logout (line 849) | def action_logout(action_object, step_desc, value, loc):
function action_addtopo (line 857) | def action_addtopo(action_object, step_desc, value, loc):
function action_clear_topo (line 877) | def action_clear_topo(action_object, step_desc, value, loc):
function action_reset (line 897) | def action_reset(action_object, step_desc, value, loc):
function action_restartmw (line 935) | def action_restartmw(action_object, step_desc, value, loc):
function action_setadmin (line 979) | def action_setadmin(action_object, step_desc, value, loc):
function sshclient_execmd_redirection (line 1005) | def sshclient_execmd_redirection(action_object, step_desc, value, loc):
function sshclient_dpinetport (line 1076) | def sshclient_dpinetport(action_object, step_desc, value, loc):
function action_sendTrafoFlowData (line 1126) | def action_sendTrafoFlowData(action_object, step_desc, value, loc):
function action_sendEventAndIncident (line 1139) | def action_sendEventAndIncident(action_object, step_desc, value, loc):
function action_countnum (line 1157) | def action_countnum(action_object, step_desc, value, loc):
function action_ele_2_countnum (line 1176) | def action_ele_2_countnum(action_object, step_desc, value, loc):
function action_ele_2_countnum (line 1199) | def action_ele_2_countnum(action_object, step_desc, value, loc):
function action_untilshow (line 1214) | def action_untilshow(action_object, step_desc, value, loc):
function action_ipmac_switch (line 1232) | def action_ipmac_switch(action_object, step_desc, value, loc):
function action_security_detail (line 1250) | def action_security_detail(action_object, step_desc, value, loc):
function action_security_detail (line 1278) | def action_security_detail(action_object, step_desc, value, loc):
function delete_task (line 1312) | def delete_task(action_object, step_desc, value, loc):
function create_louwa_task (line 1325) | def create_louwa_task(action_object, step_desc, value, loc):
function check_description (line 1355) | def check_description(action_object, step_desc, value, loc):
FILE: seleniumkeyword/CustomKeyword.py
function action_login (line 26) | def action_login(action_object, step_desc, value, loc):
function action_reset (line 47) | def action_reset(action_object, step_desc, value, loc):
FILE: seleniumkeyword/HTMLTestRunner.py
class OutputRedirector (line 112) | class OutputRedirector(object):
method __init__ (line 114) | def __init__(self, fp):
method write (line 117) | def write(self, s):
method writelines (line 120) | def writelines(self, lines):
method flush (line 123) | def flush(self):
class Template_mixin (line 134) | class Template_mixin(object):
class _TestResult (line 675) | class _TestResult(TestResult):
method __init__ (line 679) | def __init__(self, verbosity=1, result_list=None, tag_list=None):
method startTest (line 702) | def startTest(self, test):
method complete_output (line 713) | def complete_output(self):
method stopTest (line 727) | def stopTest(self, test):
method addSuccess (line 734) | def addSuccess(self, test):
method addError (line 751) | def addError(self, test, err):
method addFailure (line 771) | def addFailure(self, test, err):
class HTMLTestRunner (line 792) | class HTMLTestRunner(Template_mixin):
method __init__ (line 795) | def __init__(self, stream=sys.stdout, verbosity=1, title=None, descrip...
method run (line 812) | def run(self, test):
method sortResult (line 821) | def sortResult(self, result_list):
method getReportAttributes (line 836) | def getReportAttributes(self, result):
method generateReport (line 858) | def generateReport(self, test, result):
method _generate_stylesheet (line 876) | def _generate_stylesheet(self):
method _generate_heading (line 880) | def _generate_heading(self, report_attrs):
method _generate_report (line 896) | def _generate_report(self, result):
method _generate_report_test (line 939) | def _generate_report_test(self, rows, cid, tid, n, t, o, e):
method _generate_ending (line 993) | def _generate_ending(self):
class TestProgram (line 1004) | class TestProgram(unittest.TestProgram):
method runTests (line 1009) | def runTests(self):
FILE: seleniumkeyword/RestApiUtil.py
function call_post (line 11) | def call_post(url_post, para_dict):
function call_get (line 21) | def call_get(url_get):
FILE: seleniumkeyword/SimulatorUtil.py
function sendFlowData (line 10) | def sendFlowData(simulatorIP, testServerIP, type):
function sendTrafoFlowData (line 20) | def sendTrafoFlowData(simulatorIP, trafoServerIp, type, timeoutSeconds=N...
function sendAuditFlowData (line 35) | def sendAuditFlowData(simulatorIP, testServerIP, type):
function sendEventAndIncident (line 48) | def sendEventAndIncident(simulatorIP, testServerIP, dpisn, type):
function generateDpiLog (line 65) | def generateDpiLog(simulatorIP, testServerIP, dpisn, type):
FILE: seleniumkeyword/TestSuite.py
class TestSuite (line 24) | class TestSuite(unittest.TestCase):
method tearDown (line 25) | def tearDown(self):
method action_test (line 33) | def action_test(self, step_list):
method generateTest (line 87) | def generateTest(step_list):
class Controller (line 101) | class Controller(object):
method update_task_history (line 122) | def update_task_history(cls):
method get_client (line 158) | def get_client(cls):
method init (line 171) | def init(cls):
method set_conn (line 184) | def set_conn(cls):
method my_execute (line 191) | def my_execute(cls, sql):
method action_test (line 200) | def action_test(cls, *args):
method set_expand_paras_dict (line 215) | def set_expand_paras_dict(cls, task_id):
method expand_paras (line 223) | def expand_paras(cls, input_text):
method update_result (line 229) | def update_result(cls):
method update_testrail (line 246) | def update_testrail(cls):
function get_args (line 262) | def get_args():
function gen_test_cass (line 280) | def gen_test_cass(suite):
function run_suite (line 379) | def run_suite():
FILE: seleniumkeyword/mwupgrade.py
class Demo (line 14) | class Demo(unittest.TestCase):
method setUp (line 17) | def setUp(self):
method test_mwupgrade (line 28) | def test_mwupgrade(self):
method tearDown (line 168) | def tearDown(self):
method get_bin (line 171) | def get_bin(self):
FILE: seleniumkeyword/popautomagic.py
function sendAutoMagic (line 11) | def sendAutoMagic(url, data):
FILE: seleniumkeyword/result/highcharts.js
function v (line 12) | function v(a){var e,b;for(q=a.length;q--;)e="M"===a[q]||"L"===a[q],b=/[a...
function l (line 13) | function l(a,e){for(;a.length<m;){a[0]=e[m-a.length];var b=a.slice(0,t);...
function u (line 13) | function u(a,e){for(var c=(m-a.length)/t;0<c&&c--;)b=a.slice().splice(a....
function v (line 26) | function v(a){a.target=a.srcElement||
function v (line 27) | function v(a,c){h.removeEventListener?h.removeEventListener(a,c,!1):h.at...
function l (line 27) | function l(){var a,c;if(h.nodeName)for(c in f?(a={},a[f]=!0):a=d,a)if(d[...
function D (line 109) | function D(){var h=a.defaultOptions.global,l,u=h.useUTC,d=u?"getUTC":"ge...
function a (line 221) | function a(a){this[a]&&(this[a]=this[a].destroy())}
function b (line 240) | function b(b){return b.id===
function b (line 296) | function b(){var b={width:c.yAxis.len,height:c.xAxis.len};u(["group","ma...
function a (line 300) | function a(c,e,g){var d,k;if(k=c&&c.length)return d=b.kdAxisArray[e%g],c...
function c (line 301) | function c(a,b,f,h){var m=b.point,n=e.kdAxisArray[f%h],r,q,t=m;q=l(a[d])...
function D (line 302) | function D(a,d,c,f,h){var n=a.chart.inverted;this.axis=a;this.isNegative...
function e (line 316) | function e(){f.applyOptions(a);null===f.y&&m&&(f.graphic=m.destroy());n(...
function e (line 319) | function e(){d.destroy();
function b (line 348) | function b(a,b){return a.target-b.target}
function f (line 362) | function f(){var f=[];C(a.series,function(a){var h=a.options.dataLabels,...
function h (line 383) | function h(a,d,c){var l,p;for(l in a)if(-1<G(l,["series","xAxis","yAxis"...
FILE: seleniumkeyword/sendlog/guitest.py
function sel_radio (line 27) | def sel_radio():
function sendlog (line 44) | def sendlog():
function stopsend (line 60) | def stopsend():
function sel_filetype (line 71) | def sel_filetype(event):
function sel_logtype (line 82) | def sel_logtype(event):
function checkfile (line 101) | def checkfile():
function add_btn (line 131) | def add_btn():
FILE: seleniumkeyword/sendlog/randomip.py
function get_random_ip (line 13) | def get_random_ip(RANDOM_IP_POOL):
function get_random_mac (line 29) | def get_random_mac():
FILE: seleniumkeyword/sendlog/sendingdata.py
class Controller (line 18) | class Controller(object):
method init (line 21) | def init(cls):
function get_args (line 25) | def get_args():
function run (line 42) | def run(srcip, dstip,data,protocol,dport,count,speed):
function sendpkgdata (line 51) | def sendpkgdata():
FILE: seleniumkeyword/sendlog/syslogc.py
class send (line 18) | class send:
method __init__ (line 19) | def __init__(self, message, host, port):
method run (line 48) | def run(self):
FILE: seleniumkeyword/sendlog/tcpsendingsyslog.py
class Controller (line 16) | class Controller(object):
method init (line 19) | def init(cls):
function get_args (line 23) | def get_args():
function run (line 37) | def run(host,port,data,count):
function senddata (line 48) | def senddata():
FILE: seleniumkeyword/sendlog/udpsendingsyslog.py
class sending (line 17) | class sending(threading.Thread):
method __init__ (line 19) | def __init__(self):
method usage (line 199) | def usage(self):
method run (line 216) | def run(self):
method stop (line 296) | def stop(self):
function sendfile (line 299) | def sendfile():
FILE: seleniumkeyword/sendlog/weighted_choice.py
function weighted_choice_sub (line 13) | def weighted_choice_sub(weights):
FILE: seleniumkeyword/testrail.py
class APIClient (line 15) | class APIClient:
method __init__ (line 16) | def __init__(self, base_url):
method send_get (line 34) | def send_get(self, uri):
method send_post (line 50) | def send_post(self, uri, data):
method __send_request (line 53) | def __send_request(self, method, uri, data):
class APIError (line 83) | class APIError(Exception):
Condensed preview — 213 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,531K chars).
[
{
"path": "Dockerfile",
"chars": 826,
"preview": "FROM ubuntu:18.04\n\nMAINTAINER ray<tsbc@vip.qq.com>\n\nLABEL version=\"2.0\" by=\"ray\" descriptio=\"python3.6 django 3.2.3\"\n\nEN"
},
{
"path": "LICENSE",
"chars": 18038,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
},
{
"path": "README.md",
"chars": 1595,
"preview": "# 自动化测试平台 \n## python3.8+ Django 3.2.10框架\n>python3.8以下版本 使用Django 3.0.5 以上版本 ,django的 /admin/后台会异常退出,不使用/admin/后台不影响,安装"
},
{
"path": "auto_auth/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "auto_auth/admin.py",
"chars": 63,
"preview": "from django.contrib import admin\n\n# Register your models here.\n"
},
{
"path": "auto_auth/apps.py",
"chars": 92,
"preview": "from django.apps import AppConfig\n\n\nclass AutoAuthConfig(AppConfig):\n name = 'auto_auth'\n"
},
{
"path": "auto_auth/forms.py",
"chars": 1241,
"preview": "# -*- coding: utf-8 -*-\nfrom django import forms\nfrom django.contrib.auth.models import User\nfrom django.contrib.auth.fo"
},
{
"path": "auto_auth/migrations/0001_initial.py",
"chars": 3987,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.conf import settings\nimport django.contrib.auth.models\nimpo"
},
{
"path": "auto_auth/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "auto_auth/models.py",
"chars": 3404,
"preview": "# -*- coding: utf-8 -*-\n\nimport datetime\nimport secrets\n\nfrom django.db import models\nfrom django.conf import settings\nf"
},
{
"path": "auto_auth/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "auto_auth/urls.py",
"chars": 1640,
"preview": "# -*- coding: utf-8 -*-\n\nfrom django.conf.urls import url\nfrom django.urls import reverse_lazy\nfrom django.contrib.auth "
},
{
"path": "auto_auth/views.py",
"chars": 12067,
"preview": "# -*- coding: utf-8 -*-\nimport json\n\nfrom datetime import datetime\nfrom django.urls import reverse\nfrom django.conf impo"
},
{
"path": "automatic/__init__.py",
"chars": 89,
"preview": "# -*- coding: utf-8 -*-\n__version__ = '2.0'\n\nimport pymysql\npymysql.install_as_MySQLdb()\n"
},
{
"path": "automatic/asgi.py",
"chars": 402,
"preview": "\"\"\"\nASGI config for automatic project.\n\nIt exposes the ASGI callable as a module-level variable named ``application``.\n\n"
},
{
"path": "automatic/element/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/element/admin.py",
"chars": 368,
"preview": "from django.contrib import admin\n\n# Register your models here.\n\nfrom automatic.element import models\n\n\nclass ElementAdmi"
},
{
"path": "automatic/element/apps.py",
"chars": 99,
"preview": "from django.apps import AppConfig\n\n\nclass ElementConfig(AppConfig):\n name = 'automatic.element'\n"
},
{
"path": "automatic/element/forms.py",
"chars": 704,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-08\n\"\"\"\nfrom django import forms\nfrom automati"
},
{
"path": "automatic/element/migrations/0001_initial.py",
"chars": 1515,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.db import migrations, models\nimport django.db.models.deleti"
},
{
"path": "automatic/element/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/element/models.py",
"chars": 1282,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom django.db import models\nfrom auto"
},
{
"path": "automatic/element/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/element/urls.py",
"chars": 554,
"preview": "from django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\nfrom automatic.element import"
},
{
"path": "automatic/element/views.py",
"chars": 5643,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-08\n\"\"\"\nimport json\nfrom django.utils import t"
},
{
"path": "automatic/keywords/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/keywords/admin.py",
"chars": 333,
"preview": "from django.contrib import admin\n\n# Register your models here.\n\nfrom automatic.keywords import models\n\n\nclass KeywordAdm"
},
{
"path": "automatic/keywords/apps.py",
"chars": 101,
"preview": "from django.apps import AppConfig\n\n\nclass KeywordsConfig(AppConfig):\n name = 'automatic.keywords'\n"
},
{
"path": "automatic/keywords/fixtures/initial_data.json",
"chars": 9818,
"preview": "[\n {\n \"model\": \"keywords.keyword\",\n \"pk\": 1,\n \"fields\": {\n \"productid\": 0,\n "
},
{
"path": "automatic/keywords/migrations/0001_initial.py",
"chars": 1062,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.M"
},
{
"path": "automatic/keywords/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/keywords/models.py",
"chars": 775,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom django.db import models\n# Create "
},
{
"path": "automatic/keywords/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/keywords/urls.py",
"chars": 555,
"preview": "from django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\nfrom automatic.keywords impor"
},
{
"path": "automatic/keywords/views.py",
"chars": 3752,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-08\n\"\"\"\nimport json\n\nfrom django.utils import "
},
{
"path": "automatic/management/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/management/admin.py",
"chars": 802,
"preview": "from django.contrib import admin\n\n# Register your models here.\n\nfrom automatic.management import models\n\n\nclass ProductA"
},
{
"path": "automatic/management/apps.py",
"chars": 105,
"preview": "from django.apps import AppConfig\n\n\nclass ManagementConfig(AppConfig):\n name = 'automatic.management'\n"
},
{
"path": "automatic/management/migrations/0001_initial.py",
"chars": 4354,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.conf import settings\nfrom django.db import migrations, mode"
},
{
"path": "automatic/management/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/management/models.py",
"chars": 3452,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom __future__ import unicode_literal"
},
{
"path": "automatic/management/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/management/urls.py",
"chars": 1970,
"preview": "from django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\nfrom automatic.management imp"
},
{
"path": "automatic/management/views.py",
"chars": 16373,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nimport logging,json\nfrom django.utils "
},
{
"path": "automatic/settings/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/settings/common.py",
"chars": 5192,
"preview": "\"\"\"\nDjango settings for automatic project.\n\nGenerated by 'django-admin startproject' using Django 3.0.2.\n\nFor more infor"
},
{
"path": "automatic/signals.py",
"chars": 92,
"preview": "from django.dispatch import Signal\n\nUSER_REGISTERED_SIGNAL = Signal(providing_args=['user'])"
},
{
"path": "automatic/static/css/ak-base-style.css",
"chars": 31808,
"preview": "@charset \"utf-8\";\nbody { font-size:12px; font-family:Arial,'Microsoft Yahei'; color:#555;} \n\n.ak-clear { clear:bot"
},
{
"path": "automatic/static/css/ak-schedule.css",
"chars": 31332,
"preview": ".ak-zper-ltopbtnbox{background:#fafafa;height:50px;position:relative;border-bottom: solid 1px #eee;box-shadow: 0 0 8px #"
},
{
"path": "automatic/static/css/bootstrap-theme.css",
"chars": 26132,
"preview": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "automatic/static/css/bootstrap.css",
"chars": 147430,
"preview": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "automatic/static/css/bootstrapValidator.css",
"chars": 472,
"preview": "/**\n * BootstrapValidator (http://bootstrapvalidator.com)\n * The best jQuery plugin to validate form fields. Designed to"
},
{
"path": "automatic/static/css/font-awesome/css/font-awesome-ie7.css",
"chars": 41310,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome/css/font-awesome.css",
"chars": 27231,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome/less/animated.less",
"chars": 713,
"preview": "// Animated Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n -webkit-animation: fa-spin 2s infinite linea"
},
{
"path": "automatic/static/css/font-awesome/less/bootstrap.less",
"chars": 2084,
"preview": "/* BOOTSTRAP SPECIFIC CLASSES\n * -------------------------- */\n\n/* Bootstrap 2.0 sprites.less reset */\n[class^=\"icon-\"],"
},
{
"path": "automatic/static/css/font-awesome/less/bordered-pulled.less",
"chars": 330,
"preview": "// Bordered & Pulled\n// -------------------------\n\n.@{fa-css-prefix}-border {\n padding: .2em .25em .15em;\n border: sol"
},
{
"path": "automatic/static/css/font-awesome/less/core.less",
"chars": 2101,
"preview": "/* FONT AWESOME CORE\n * -------------------------- */\n\n[class^=\"icon-\"],\n[class*=\" icon-\"] {\n .icon-FontAwesome();\n}\n\n["
},
{
"path": "automatic/static/css/font-awesome/less/extras.less",
"chars": 2398,
"preview": "/* EXTRAS\n * -------------------------- */\n\n/* Stacked and layered icon */\n.icon-stack();\n\n/* Animated rotating icon */\n"
},
{
"path": "automatic/static/css/font-awesome/less/fixed-width.less",
"chars": 119,
"preview": "// Fixed Width Icons\n// -------------------------\n.@{fa-css-prefix}-fw {\n width: (18em / 14);\n text-align: center;\n}\n"
},
{
"path": "automatic/static/css/font-awesome/less/font-awesome-ie7.less",
"chars": 19298,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome/less/font-awesome.less",
"chars": 1318,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome/less/icons.less",
"chars": 17555,
"preview": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n readers do not read off random characters th"
},
{
"path": "automatic/static/css/font-awesome/less/larger.less",
"chars": 370,
"preview": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.@{fa-css-pre"
},
{
"path": "automatic/static/css/font-awesome/less/list.less",
"chars": 377,
"preview": "// List Icons\n// -------------------------\n\n.@{fa-css-prefix}-ul {\n padding-left: 0;\n margin-left: @fa-li-width;\n lis"
},
{
"path": "automatic/static/css/font-awesome/less/mixins.less",
"chars": 1041,
"preview": "// Mixins\n// --------------------------\n\n.icon(@icon) {\n .icon-FontAwesome();\n content: @icon;\n}\n\n.icon-FontAwesome() "
},
{
"path": "automatic/static/css/font-awesome/less/path.less",
"chars": 742,
"preview": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n font-family: 'FontAwesome';\n src: url('@{FontAwesomePath}"
},
{
"path": "automatic/static/css/font-awesome/less/rotated-flipped.less",
"chars": 622,
"preview": "// Rotated & Flipped Icons\n// -------------------------\n\n.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }\n.@"
},
{
"path": "automatic/static/css/font-awesome/less/stacked.less",
"chars": 476,
"preview": "// Stacked Icons\n// -------------------------\n\n.@{fa-css-prefix}-stack {\n position: relative;\n display: inline-block;\n"
},
{
"path": "automatic/static/css/font-awesome/less/variables.less",
"chars": 8888,
"preview": "// Variables\n// --------------------------\n\n@FontAwesomePath: \"../font\";\n//@FontAwesomePath: \"//netdna.bootstrapcd"
},
{
"path": "automatic/static/css/font-awesome/scss/_animated.scss",
"chars": 715,
"preview": "// Spinning Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n -webkit-animation: fa-spin 2s infinite line"
},
{
"path": "automatic/static/css/font-awesome/scss/_bootstrap.scss",
"chars": 2088,
"preview": "/* BOOTSTRAP SPECIFIC CLASSES\n * -------------------------- */\n\n/* Bootstrap 2.0 sprites.less reset */\n[class^=\"icon-\"],"
},
{
"path": "automatic/static/css/font-awesome/scss/_bordered-pulled.scss",
"chars": 332,
"preview": "// Bordered & Pulled\n// -------------------------\n\n.#{$fa-css-prefix}-border {\n padding: .2em .25em .15em;\n border: so"
},
{
"path": "automatic/static/css/font-awesome/scss/_core.scss",
"chars": 2157,
"preview": "/* FONT AWESOME CORE\n * -------------------------- */\n\n[class^=\"icon-\"],\n[class*=\" icon-\"] {\n @include icon-FontAwesome"
},
{
"path": "automatic/static/css/font-awesome/scss/_extras.scss",
"chars": 2406,
"preview": "/* EXTRAS\n * -------------------------- */\n\n/* Stacked and layered icon */\n@include icon-stack();\n\n/* Animated rotating "
},
{
"path": "automatic/static/css/font-awesome/scss/_fixed-width.scss",
"chars": 120,
"preview": "// Fixed Width Icons\n// -------------------------\n.#{$fa-css-prefix}-fw {\n width: (18em / 14);\n text-align: center;\n}\n"
},
{
"path": "automatic/static/css/font-awesome/scss/_icons.scss",
"chars": 17555,
"preview": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n * readers do not read off random characters th"
},
{
"path": "automatic/static/css/font-awesome/scss/_larger.scss",
"chars": 375,
"preview": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.#{$fa-css-pr"
},
{
"path": "automatic/static/css/font-awesome/scss/_list.scss",
"chars": 378,
"preview": "// List Icons\n// -------------------------\n\n.#{$fa-css-prefix}-ul {\n padding-left: 0;\n margin-left: $fa-li-width;\n li"
},
{
"path": "automatic/static/css/font-awesome/scss/_mixins.scss",
"chars": 1078,
"preview": "// Mixins\n// --------------------------\n\n@mixin icon($icon) {\n @include icon-FontAwesome();\n content: $icon;\n}\n\n@mixin"
},
{
"path": "automatic/static/css/font-awesome/scss/_path.scss",
"chars": 753,
"preview": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n font-family: 'FontAwesome';\n src: url('#{$FontAwesomePath"
},
{
"path": "automatic/static/css/font-awesome/scss/_rotated-flipped.scss",
"chars": 672,
"preview": "// Rotated & Flipped Icons\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, "
},
{
"path": "automatic/static/css/font-awesome/scss/_stacked.scss",
"chars": 482,
"preview": "// Stacked Icons\n// -------------------------\n\n.#{$fa-css-prefix}-stack {\n position: relative;\n display: inline-block;"
},
{
"path": "automatic/static/css/font-awesome/scss/_variables.scss",
"chars": 8061,
"preview": "// Variables\n// --------------------------\n\n$FontAwesomePath: \"../font\" !default;\n$FontAwesomeVersion: \"3.2.1\" !default;"
},
{
"path": "automatic/static/css/font-awesome/scss/font-awesome-ie7.scss",
"chars": 22327,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome/scss/font-awesome.scss",
"chars": 1283,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/font-awesome.css",
"chars": 27231,
"preview": "/*!\n * Font Awesome 3.2.1\n * the iconic font designed for Bootstrap\n * ----------------------------------------------"
},
{
"path": "automatic/static/css/jquery-ui.css",
"chars": 37326,
"preview": "/*! jQuery UI - v1.12.1 - 2016-09-14\n* http://jqueryui.com\n* Includes: core.css, accordion.css, autocomplete.css, menu.c"
},
{
"path": "automatic/static/css/login-app.css",
"chars": 468757,
"preview": "@charset \"UTF-8\";html{overflow:visible}body,input,textarea{font-family:'微软雅黑','Helvetica Neue',sans-serif,SimHei;-webkit"
},
{
"path": "automatic/static/css/login-vendor.css",
"chars": 308620,
"preview": "@charset \"UTF-8\";.ui.breadcrumb{margin:1em 0;display:inline-block;vertical-align:middle}.ui.breadcrumb:first-child{margi"
},
{
"path": "automatic/static/css/page-v3/ak-master-page-v3.css",
"chars": 35298,
"preview": "@charset \"UTF-8\";\n/*Zara*/\nbody {\n font-family: Arial,'Microsoft Yahei' !important;\n}\n.ak-zmaster-sidebar-height{heig"
},
{
"path": "automatic/static/css/page-v3/ak-master-page-v3style.css",
"chars": 33793,
"preview": "@charset \"UTF-8\";\n/*\n *\n * RENAISSANCE - Responsive Admin Theme\n * version 1.3.0\n *\n*/\n\n.preloader {\n position: fix"
},
{
"path": "automatic/static/css/wheelmenu.css",
"chars": 2524,
"preview": "/* Required Stylesheets */\n\na {\n text-decoration: none;\n}\n\n.wheel-button {\n position: relative;\n}\n\n.wheel {\n ma"
},
{
"path": "automatic/static/js/automagic.js",
"chars": 35301,
"preview": "/**\n * Created by ray on 16-9-9.\n */\n\n\n\n\nfunction getUrlParam(name) {\n var reg = new RegExp(\"(^|&)\" + name + \"=([^&]*"
},
{
"path": "automatic/static/js/back-to-top.js",
"chars": 3765,
"preview": "//** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.\n//** Availa"
},
{
"path": "automatic/static/js/bootstrapValidator.js",
"chars": 256290,
"preview": "/*!\n * BootstrapValidator (http://bootstrapvalidator.com)\n * The best jQuery plugin to validate form fields. Designed to"
},
{
"path": "automatic/static/js/casemanage.js",
"chars": 9999,
"preview": "/**\n * Created by ray on 16-11-2.\n */\n\nvar keywordlist = []\n$(document).ready(function(){\n /* 根据项目查询元素进行模糊搜索匹配 */\n"
},
{
"path": "automatic/static/js/common.js",
"chars": 1656,
"preview": "/*\n *\n * RENAISSANCE - Responsive Admin Theme\n * version 1.3.0\n *\n*/\n\nvar datetime = null,\n date = null;\n\nvar"
},
{
"path": "automatic/static/js/jquery-ui.js",
"chars": 520714,
"preview": "/*! jQuery UI - v1.12.1 - 2016-09-14\n* http://jqueryui.com\n* Includes: widget.js, position.js, data.js, disable-selectio"
},
{
"path": "automatic/static/js/jquery.wheelmenu.js",
"chars": 7932,
"preview": "/* ===========================================================\n * jquery-wheelmenu.js v1\n * ============================"
},
{
"path": "automatic/static/js/keyword.js",
"chars": 1824,
"preview": "/**\n * Created by Ray on 16-11-11.\n */\n\n/* 点击关键字编辑按钮 */\nfunction setkeywordValue(id){\n\n $.ajax({\n type:\""
},
{
"path": "automatic/static/js/taskmanage.js",
"chars": 9889,
"preview": "/**\n * Created by ray on 16-11-2.\n */\n\t\tvar MoveTest = {\n\t\t\terrorMsg: \"放错了...请选择正确的类别!\",\n\t\t\tcurTarget: null,\n\t\t\tcurTmpTa"
},
{
"path": "automatic/static/muti_select/css/multi.css",
"chars": 962,
"preview": "\n.multi_select {\n\theight:auto;\n\toverflow:hidden;\n\tfloat:left;\n top:40px;\n}\n.multi_select_focus {\n position:absolut"
},
{
"path": "automatic/static/muti_select/css/style.css",
"chars": 371,
"preview": ".multi_select {\nwidth: 100%;\nheight: 200px;\nbackground-color: #fff;\nmargin-top: -9px;\noverflow-y: auto;\n}\n.multi_select "
},
{
"path": "automatic/static/muti_select/src/MultiSelectDropList.js",
"chars": 3572,
"preview": "/*\n@copyright:rwang\n@email:172247097@qq.com\n@date:2014-08-02\n*/\n\n(function ($){\n \n $.fn.extend({\n MSDL: func"
},
{
"path": "automatic/static/zTree_v3/css/awesomeStyle/awesome.css",
"chars": 8385,
"preview": "/*-------------------------------------\nzTree Style using fontawesome instead of images\n\nversion: 1.1\nauthor: Mik"
},
{
"path": "automatic/static/zTree_v3/css/awesomeStyle/awesome.less",
"chars": 8954,
"preview": "/*-------------------------------------\nzTree Style using fontawesome instead of images\n\nversion: 1.1\nauthor: Mik"
},
{
"path": "automatic/static/zTree_v3/css/awesomeStyle/fa.less",
"chars": 11398,
"preview": "@fa-glass: \"\\f000\";\n@fa-music: \"\\f001\";\n@fa-search: \"\\f002\";\n@fa-envelope-o: \"\\f003\";\n@fa-heart: \"\\f004\";\n@fa-star: \"\\f0"
},
{
"path": "automatic/static/zTree_v3/css/demo.css",
"chars": 2165,
"preview": "html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, bi"
},
{
"path": "automatic/static/zTree_v3/css/metroStyle/metroStyle.css",
"chars": 6576,
"preview": "/*-------------------------------------\nzTree Style\n\nversion: 3.4\nauthor: Hunter.z\nemail: hunter.z@263.net\nw"
},
{
"path": "automatic/static/zTree_v3/css/zTreeStyle/zTreeStyle.css",
"chars": 6223,
"preview": "/*-------------------------------------\nzTree Style\n\nversion:\t3.5.19\nauthor:\t\tHunter.z\nemail:\t\thunter.z@263.net\nwebsite:"
},
{
"path": "automatic/static/zTree_v3/js/jquery.ztree.all.js",
"chars": 123580,
"preview": "\n/*\n * JQuery zTree core v3.5.25\n * http://zTree.me/\n *\n * Copyright (c) 2010 Hunter.z\n *\n * Licensed same as jquery - M"
},
{
"path": "automatic/static/zTree_v3/js/jquery.ztree.core.js",
"chars": 59131,
"preview": "/*\n * JQuery zTree core v3.5.25\n * http://zTree.me/\n *\n * Copyright (c) 2010 Hunter.z\n *\n * Licensed same as jquery - MI"
},
{
"path": "automatic/static/zTree_v3/js/jquery.ztree.excheck.js",
"chars": 21464,
"preview": "/*\n * JQuery zTree excheck v3.5.25\n * http://zTree.me/\n *\n * Copyright (c) 2010 Hunter.z\n *\n * Licensed same as jquery -"
},
{
"path": "automatic/static/zTree_v3/js/jquery.ztree.exedit.js",
"chars": 42981,
"preview": "/*\n * JQuery zTree exedit v3.5.25\n * http://zTree.me/\n *\n * Copyright (c) 2010 Hunter.z\n *\n * Licensed same as jquery - "
},
{
"path": "automatic/static/zTree_v3/js/jquery.ztree.exhide.js",
"chars": 10458,
"preview": "/*\n * JQuery zTree exHideNodes v3.5.25\n * http://zTree.me/\n *\n * Copyright (c) 2010 Hunter.z\n *\n * Licensed same as jque"
},
{
"path": "automatic/templates/404.html",
"chars": 201,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %} \n<div style=\"text-align:center"
},
{
"path": "automatic/templates/500.html",
"chars": 215,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div style=\"text-align:cen"
},
{
"path": "automatic/templates/base.html",
"chars": 525,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>{% block title %}Default Title{% endblock "
},
{
"path": "automatic/templates/comingsoon.html",
"chars": 202,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %} \n<div style=\"text-align:center"
},
{
"path": "automatic/templates/element/element.html",
"chars": 18005,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/frame.html",
"chars": 16136,
"preview": "{% load static %}\n<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"view"
},
{
"path": "automatic/templates/index.html",
"chars": 13533,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/keywords/keyword.html",
"chars": 15207,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n {% if request.user.is_admi"
},
{
"path": "automatic/templates/management/moduleadd.html",
"chars": 369,
"preview": "{% extends 'nav.html' %}\n{% block title %}Module Add{% endblock %}\n\n{% block slideshow %}\n <br/><br/><br/>\n<form meth"
},
{
"path": "automatic/templates/management/moduleview.html",
"chars": 2040,
"preview": "{% extends 'nav.html' %}\n{% block title %}Module View{% endblock %}\n\n{% block slideshow %}\n <br/><br/><br/>\n<body>\n{%"
},
{
"path": "automatic/templates/management/productadd.html",
"chars": 363,
"preview": "{% extends 'nav.html' %}\n{% block title %}Product Add{% endblock %}\n\n{% block slideshow %}\n <br/><br/><br/>\n<form met"
},
{
"path": "automatic/templates/management/productlist.html",
"chars": 19943,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n {% if request.user.is_admi"
},
{
"path": "automatic/templates/management/productview.html",
"chars": 17005,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <!--======================"
},
{
"path": "automatic/templates/management/projectadd.html",
"chars": 371,
"preview": "{% extends 'nav.html' %}\n{% block title %}Project Add{% endblock %}\n\n{% block slideshow %}\n <br/><br/><br/>\n<form met"
},
{
"path": "automatic/templates/management/projectlist.html",
"chars": 4337,
"preview": "{% extends 'nav.html' %}\n{% block title %}Project List{% endblock %}\n{% block slideshow %}\n <br/><br/><br/>\n <form"
},
{
"path": "automatic/templates/management/projectview.html",
"chars": 14248,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <!--======================"
},
{
"path": "automatic/templates/management/syslog.html",
"chars": 2335,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n {% load static %}\n <div"
},
{
"path": "automatic/templates/nav.html",
"chars": 12941,
"preview": "{% load static %}\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>{% block title %}Base{% "
},
{
"path": "automatic/templates/oauth/userlist.html",
"chars": 39651,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n {% if request.user.is_staf"
},
{
"path": "automatic/templates/registration/login.html",
"chars": 6613,
"preview": "{% load static %}\n<!DOCTYPE html>\n<html>\n<head>\n <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"
},
{
"path": "automatic/templates/testcase/caseadd.html",
"chars": 6689,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/testcase/casecopy.html",
"chars": 20319,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/testcase/caseedit.html",
"chars": 16177,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/testcase/caselist.html",
"chars": 4181,
"preview": "{% extends 'nav.html' %}\n{% block title %}Case List{% endblock %}\n{% block slideshow %}\n <br/><br/><br/>\n <form cl"
},
{
"path": "automatic/templates/testcase/caseview.html",
"chars": 8133,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/testtask/taskadd.html",
"chars": 11576,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n\n <div class=\"ak-zper-midbo"
},
{
"path": "automatic/templates/testtask/taskedit.html",
"chars": 27800,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n\n <div class=\"ak-zper-midbo"
},
{
"path": "automatic/templates/testtask/tasklist.html",
"chars": 21977,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/templates/webinterface/webinterface.html",
"chars": 19730,
"preview": "{% extends 'frame.html' %}\n{% block title %}Automagic{% endblock %}\n{% block slideshow %}\n <div class=\"ak-zper-midbox"
},
{
"path": "automatic/testcase/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/testcase/admin.py",
"chars": 558,
"preview": "from django.contrib import admin\n\n# Register your models here.\n\nfrom automatic.testcase import models\n\n\nclass CaseAdmin("
},
{
"path": "automatic/testcase/apps.py",
"chars": 101,
"preview": "from django.apps import AppConfig\n\n\nclass TestcaseConfig(AppConfig):\n name = 'automatic.testcase'\n"
},
{
"path": "automatic/testcase/forms.py",
"chars": 458,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom django import forms\nfrom automati"
},
{
"path": "automatic/testcase/migrations/0001_initial.py",
"chars": 3690,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nimport django.core.validators\nfrom django.db import migrations, models\n"
},
{
"path": "automatic/testcase/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/testcase/models.py",
"chars": 2709,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom django.db import models\nfrom auto"
},
{
"path": "automatic/testcase/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/testcase/urls.py",
"chars": 845,
"preview": "from django.conf.urls import url\nfrom django.urls import reverse_lazy\nfrom django.contrib.auth import views as contrib_a"
},
{
"path": "automatic/testcase/views.py",
"chars": 13210,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nimport os\nfrom django.contrib.auth.dec"
},
{
"path": "automatic/testtask/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/testtask/admin.py",
"chars": 867,
"preview": "from django.contrib import admin\n\n# Register your models here.\n\nfrom automatic.testtask import models\n\n\nclass KeywordAdm"
},
{
"path": "automatic/testtask/apps.py",
"chars": 101,
"preview": "from django.apps import AppConfig\n\n\nclass TesttaskConfig(AppConfig):\n name = 'automatic.testtask'\n"
},
{
"path": "automatic/testtask/migrations/0001_initial.py",
"chars": 4596,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.conf import settings\nfrom django.db import migrations, mode"
},
{
"path": "automatic/testtask/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/testtask/models.py",
"chars": 3619,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nfrom django.db import models\nfrom auto"
},
{
"path": "automatic/testtask/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/testtask/urls.py",
"chars": 609,
"preview": "from django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\nfrom automatic.testtask impor"
},
{
"path": "automatic/testtask/views.py",
"chars": 11731,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-06\n\"\"\"\nimport logging, json, os\nimport jenkin"
},
{
"path": "automatic/urls.py",
"chars": 1942,
"preview": "\"\"\"automatic URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n https:"
},
{
"path": "automatic/webinterface/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/webinterface/admin.py",
"chars": 1251,
"preview": "from django import forms\nfrom django.contrib import admin\n# Register your models here.\nfrom automatic.webinterface impor"
},
{
"path": "automatic/webinterface/apps.py",
"chars": 150,
"preview": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass WebinterfaceConfig(AppConfig):\n na"
},
{
"path": "automatic/webinterface/migrations/0001_initial.py",
"chars": 3886,
"preview": "# Generated by Django 3.0.2 on 2020-01-15 10:02\n\nfrom django.db import migrations, models\nimport django.db.models.deleti"
},
{
"path": "automatic/webinterface/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "automatic/webinterface/models.py",
"chars": 3345,
"preview": "# -*- coding:utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-08\n\"\"\"\n\nfrom __future__ import unicode_litera"
},
{
"path": "automatic/webinterface/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "automatic/webinterface/urls.py",
"chars": 311,
"preview": "from django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\nfrom automatic.webinterface i"
},
{
"path": "automatic/webinterface/views.py",
"chars": 2940,
"preview": "from django.http import HttpResponse\nfrom automatic.webinterface.models import *\nfrom django.views.generic import ListVi"
},
{
"path": "automatic/wsgi.py",
"chars": 395,
"preview": "\"\"\"\nWSGI config for automatic project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\n"
},
{
"path": "docker-compose.yml",
"chars": 315,
"preview": "version: '2.0'\nservices:\n mariadb:\n image: tsbc520/automagic:2.0\n container_name: \"automagic\"\n restart: always"
},
{
"path": "init.sh",
"chars": 394,
"preview": "#!/bin/bash\nset -e\n\necho '生成Django表结构....'\npython3 manage.py makemigrations\necho 'Django表结构更新完成.'\n\necho '创建表结构....'\npyth"
},
{
"path": "insertkeyword.sql",
"chars": 2937,
"preview": "INSERT INTO `keywords_keyword` VALUES ('2', 0, 'click', '点击', now(), 'admin', now(), 'admin');\nINSERT INTO `keywords_key"
},
{
"path": "manage.py",
"chars": 636,
"preview": "#!/usr/bin/env python\n\"\"\"Django's command-line utility for administrative tasks.\"\"\"\nimport os\nimport sys\n\n\ndef main():\n "
},
{
"path": "requirements/base.txt",
"chars": 101,
"preview": "django==3.2.18\npyMySql==1.0.2\ntestrail==0.3.13\npython-jenkins==1.7.0\nrequests==2.25.1\nnameko==2.14.0\n"
},
{
"path": "requirements/seleniumreq.txt",
"chars": 47,
"preview": "selenium==3.141.0\nparamiko==2.10.1\nscapy==2.4.3"
},
{
"path": "seleniumkeyword/AddCase.py",
"chars": 5057,
"preview": "# -*- coding: utf-8 -*-\n\nimport argparse\nimport testrail\nimport MySQLdb\n\n\ndef get_args():\n '''\n 获取命令行参数\n :retur"
},
{
"path": "seleniumkeyword/Base.py",
"chars": 38208,
"preview": "# -*- coding: utf-8 -*-\n\nimport time,datetime\nimport os,sys\nfrom selenium.webdriver.support.wait import WebDriverWait\nfr"
},
{
"path": "seleniumkeyword/CustomKeyword.py",
"chars": 4090,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2017-01-19\n\"\"\"\nfrom Base import *\n\n\n################"
},
{
"path": "seleniumkeyword/HTMLTestRunner.py",
"chars": 31567,
"preview": "\"\"\"\nA TestRunner for use with the Python unit testing framework. It\ngenerates a HTML report to show the result at a glan"
},
{
"path": "seleniumkeyword/README.MD",
"chars": 1456,
"preview": "# Seleniumkeyword介绍 #\n\nseleniumkword是客户端执行脚本,AutoMagic的执行效果展示主要靠它来体现,它的执行依附于web平台存储的用例和场景数据,seleniumkeyword可以不需要部署在服务器端,"
},
{
"path": "seleniumkeyword/RestApiUtil.py",
"chars": 635,
"preview": "# -*-coding:utf-8-*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2016-09-03\n\"\"\"\nimport requests\nimport json\n\n\ndef call_p"
},
{
"path": "seleniumkeyword/SimulatorUtil.py",
"chars": 3453,
"preview": "# -*-coding:utf-8-*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2016-09-03\n\"\"\"\nfrom RestApiUtil import call_get, call_p"
},
{
"path": "seleniumkeyword/TestSuite.py",
"chars": 14379,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2020-01-14\n\"\"\"\n\nimport argparse\nimport os\nimport tim"
},
{
"path": "seleniumkeyword/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "seleniumkeyword/data/readme.md",
"chars": 15,
"preview": "### 浏览器文件下载默认目录"
},
{
"path": "seleniumkeyword/mwupgrade.py",
"chars": 5537,
"preview": "# -*- coding:utf-8 -*-\nimport re\n\nimport paramiko\n\n__author__ = 'Ray'\nfrom selenium import webdriver\nimport unittest\nimp"
},
{
"path": "seleniumkeyword/popautomagic.py",
"chars": 2370,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"\n__author__ = 'Ray'\nmail:tsbc@vip.qq.com\n2017-03-01\n\"\"\"\n\nimport requests, json\n\n\ndef sendAuto"
},
{
"path": "seleniumkeyword/result/highcharts.js",
"chars": 192680,
"preview": "/*\n Highcharts JS v5.0.6 (2016-12-07)\n\n (c) 2009-2016 Torstein Honsi\n\n License: www.highcharts.com/license\n*/\n(function("
},
{
"path": "seleniumkeyword/sendlog/README.md",
"chars": 1207,
"preview": "#流量回放模式(Linux)\n\n##通过回放Syslog流进行发送syslog(UDP支持源地址伪装)|sendingdata.py\n\n**usage:**</br>\nsendingdata.py [-h] [-sip SRCIP] [-d"
},
{
"path": "seleniumkeyword/sendlog/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "seleniumkeyword/sendlog/guitest.py",
"chars": 5228,
"preview": "# -*- coding: utf-8 -*-\n__author__ = 'Ray'\n\n\"\"\"\nGUI 设计.\nmail:tsbc@vip.qq.com\n2016-05-05\nhttp://blog.csdn.net/jcodeer?vie"
},
{
"path": "seleniumkeyword/sendlog/mysetup.py",
"chars": 173,
"preview": "# -*- coding: utf-8 -*-\n# mysetup.py \n\nfrom distutils.core import setup \nimport py2exe \n\n\n\"\"\"\nPy2exe打包程序\n执行:python myset"
},
{
"path": "seleniumkeyword/sendlog/randip.py",
"chars": 397,
"preview": "# -*- coding:utf-8 -*-\n\n\n__author__ = 'Ray'\n\nimport random\nimport struct\nfrom scapy.all import *\nfrom scapy.layers.inet "
},
{
"path": "seleniumkeyword/sendlog/randomip.py",
"chars": 1219,
"preview": "__author__ = 'ray'\n\nimport random\nimport socket\nimport struct\nfrom configparser import ConfigParser\n\n# cf = ConfigParser"
}
]
// ... and 13 more files (download for full content)
About this extraction
This page contains the full source code of the radiateboy/automagic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 213 files (3.2 MB), approximately 838.5k tokens, and a symbol index with 438 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.