├── 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
│ │ │ ├── css
│ │ │ │ ├── font-awesome-ie7.css
│ │ │ │ ├── font-awesome-ie7.min.css
│ │ │ │ ├── font-awesome.css
│ │ │ │ ├── font-awesome.css.map
│ │ │ │ └── font-awesome.min.css
│ │ │ ├── font
│ │ │ │ ├── FontAwesome.otf
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ └── fontawesome-webfont.woff
│ │ │ ├── fonts
│ │ │ │ ├── FontAwesome.otf
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ ├── fontawesome-webfont.woff
│ │ │ │ └── fontawesome-webfont.woff2
│ │ │ ├── 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
│ │ ├── jquery-ui.css
│ │ ├── jquery.dataTables.min.css
│ │ ├── login-app.css
│ │ ├── login-vendor.css
│ │ ├── page-v3
│ │ │ ├── ak-master-page-v3.css
│ │ │ └── ak-master-page-v3style.css
│ │ └── wheelmenu.css
│ ├── fonts
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ ├── glyphicons-halflings-regular.woff2
│ │ └── meteocons
│ │ │ ├── meteocons-webfont.eot
│ │ │ ├── meteocons-webfont.svg
│ │ │ ├── meteocons-webfont.ttf
│ │ │ └── meteocons-webfont.woff
│ ├── image
│ │ ├── background.jpg
│ │ ├── background1.jpg
│ │ ├── background2.jpg
│ │ ├── favicon.ico
│ │ ├── logo.png
│ │ └── wx.jpg
│ ├── images
│ │ ├── ak-common.png
│ │ ├── ak-person-icon01.png
│ │ ├── ak-person-icon02.jpg
│ │ ├── ak-person-icon03.png
│ │ ├── ak-person-icon04.png
│ │ ├── ak-person-icon05.png
│ │ ├── ak-person-icon06.png
│ │ ├── ak-z-icon.png
│ │ ├── app.png
│ │ ├── app_current.png
│ │ ├── background.jpg
│ │ ├── background1.jpg
│ │ ├── background2.jpg
│ │ ├── channel.png
│ │ ├── channel_current.png
│ │ ├── chat01.png
│ │ ├── cloud.png
│ │ ├── cloud_current.png
│ │ ├── custom.png
│ │ ├── custom_current.png
│ │ ├── dotted.png
│ │ ├── download.png
│ │ ├── favicon.ico
│ │ ├── home.png
│ │ ├── home_current.png
│ │ ├── icon.png
│ │ ├── line_bg.png
│ │ ├── logo-automagic.png
│ │ ├── logo.png
│ │ ├── select_xl.png
│ │ ├── select_xl01.png
│ │ ├── setting-top02.png
│ │ ├── sort_asc.png
│ │ ├── sort_both.png
│ │ ├── sort_desc.png
│ │ ├── source.png
│ │ ├── source_current.png
│ │ ├── statistics.png
│ │ ├── statistics_current.png
│ │ ├── syetem_management.png
│ │ ├── syetem_management_c.png
│ │ ├── system.png
│ │ ├── system_current.png
│ │ ├── timg.png
│ │ ├── user-13.jpg
│ │ ├── xiaoxi01.png
│ │ ├── xiaoxi01g.png
│ │ └── zkonw-back.png
│ ├── js
│ │ ├── automagic.js
│ │ ├── back-to-top.js
│ │ ├── bootstrap.min.js
│ │ ├── bootstrapValidator.js
│ │ ├── casemanage.js
│ │ ├── common.js
│ │ ├── jquery-ui.js
│ │ ├── jquery.dataTables.min.js
│ │ ├── jquery.min.js
│ │ ├── jquery.wheelmenu.js
│ │ ├── keyword.js
│ │ ├── lodash.min.js
│ │ └── taskmanage.js
│ ├── media
│ │ └── sendlog.tar
│ ├── muti_select
│ │ ├── css
│ │ │ ├── multi.css
│ │ │ └── style.css
│ │ ├── jquery-1.10.2.min.js
│ │ └── src
│ │ │ └── MultiSelectDropList.js
│ └── zTree_v3
│ │ ├── css
│ │ ├── awesomeStyle
│ │ │ ├── awesome.css
│ │ │ ├── awesome.less
│ │ │ ├── fa.less
│ │ │ └── img
│ │ │ │ └── loading.gif
│ │ ├── demo.css
│ │ ├── metroStyle
│ │ │ ├── img
│ │ │ │ ├── line_conn.png
│ │ │ │ ├── loading.gif
│ │ │ │ ├── metro.gif
│ │ │ │ └── metro.png
│ │ │ └── metroStyle.css
│ │ └── zTreeStyle
│ │ │ ├── img
│ │ │ ├── diy
│ │ │ │ ├── 1_close.png
│ │ │ │ ├── 1_open.png
│ │ │ │ ├── 2.png
│ │ │ │ ├── 3.png
│ │ │ │ ├── 4.png
│ │ │ │ ├── 5.png
│ │ │ │ ├── 6.png
│ │ │ │ ├── 7.png
│ │ │ │ ├── 8.png
│ │ │ │ └── 9.png
│ │ │ ├── line_conn.gif
│ │ │ ├── loading.gif
│ │ │ ├── zTreeStandard.gif
│ │ │ └── zTreeStandard.png
│ │ │ └── zTreeStyle.css
│ │ └── js
│ │ ├── jquery-1.4.4.min.js
│ │ ├── jquery.ztree.all.js
│ │ ├── jquery.ztree.all.min.js
│ │ ├── jquery.ztree.core.js
│ │ ├── jquery.ztree.core.min.js
│ │ ├── jquery.ztree.excheck.js
│ │ ├── jquery.ztree.excheck.min.js
│ │ ├── jquery.ztree.exedit.js
│ │ ├── jquery.ztree.exedit.min.js
│ │ ├── jquery.ztree.exhide.js
│ │ └── jquery.ztree.exhide.min.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
│ ├── img.png
│ ├── jquery.min.js
│ └── video.jpg
├── 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
└── 公众号.jpg
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:18.04
2 |
3 | MAINTAINER ray
4 |
5 | LABEL version="2.0" by="ray" descriptio="python3.6 django 3.2.3"
6 |
7 | ENV TZ=Asia/Shanghai
8 | ENV PATH=/usr/bin:$PATH
9 | ENV DEBIAN_FRONTEND=noninteractive
10 | ENV LANG C.UTF-8
11 |
12 |
13 | RUN mkdir /opt/automagic
14 | WORKDIR /opt/automagic
15 |
16 | RUN set -x;apt-get update \
17 | && apt-get install -y vim \
18 | && apt-get install -y tzdata \
19 | && apt-get install -y python3 \
20 | && apt-get install -y python3-pip \
21 | && pip3 install --upgrade pip
22 |
23 | COPY . /opt/automagic
24 |
25 | RUN pip3 --no-cache-dir install -r /opt/automagic/requirements/base.txt \
26 | -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
27 | RUN pip3 --no-cache-dir install -r /opt/automagic/requirements/seleniumreq.txt \
28 | -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
29 |
30 | ENTRYPOINT ["python3","start.py"]
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 自动化测试平台
2 | ## python3.8+ Django 3.2.10框架
3 | >python3.8以下版本 使用Django 3.0.5 以上版本 ,django的 /admin/后台会异常退出,不使用/admin/后台不影响,安装请注意版本
4 |
5 | ### [新用户指导使用指南](https://github.com/radiateboy/automagic/wiki)
6 |
7 | # (一)源码安装
8 | > pip3 install -r requirements/base.txt
9 | >
10 | > pip3 install -r requirements/seleniumreq.txt
11 |
12 | ### Mysql/Mariadb 数据库 automatic/settings/common.py
13 | ```python
14 | MYSQL_USERNAME = os.environ.get('MYSQL_USERNAME', 'root')
15 | MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', '123456')
16 | MYSQL_HOST = os.environ.get('MYSQL_HOST', 'localhost')
17 | MYSQL_PORT = os.environ.get('MYSQL_PORT', '3306')
18 | MYSQL_DBNAME = os.environ.get('MYSQL_DBNAME', 'automatic')
19 |
20 | DATABASES = {
21 | 'default': {
22 | 'ENGINE': 'django.db.backends.mysql',
23 | 'NAME': MYSQL_DBNAME,
24 | 'USER': MYSQL_USERNAME,
25 | 'PASSWORD': MYSQL_PASSWORD,
26 | 'HOST': MYSQL_HOST,
27 | 'PORT': MYSQL_PORT,
28 | }
29 | }
30 | ```
31 | #### 初始化并启动服务
32 |
33 | ```shell
34 | python3 start.py
35 | ```
36 |
37 | 另:内置关键字 在wiki #关键字创建# 页面(可以了解一下)
38 |
39 | _http://127.0.0.1:8000_ 访问登录即可
40 |
41 | 默认管理员用户:admin, 密码:admin@123
42 | # (二)docker安装
43 | ## 方法一: 命令安装启动
44 | ```shell script
45 | docker pull tsbc520/automagic:2.0
46 | ```
47 | 启动docker容器:
48 | ```shell script
49 | docker run -d -p 8000:8000 \
50 | -e MYSQL_HOST=192.168.10.167 \
51 | -e MYSQL_PORT=3306 \
52 | -e MYSQL_DBNAME=automatic \
53 | -e MYSQL_USERNAME=root \
54 | -e MYSQL_PASSWORD=123456 \
55 | tsbc520/automagic:2.0
56 | ```
57 |
58 | ## 方法二: docker-compose
59 | ```shell script
60 | docker-compose up
61 | ```
62 |
63 | ## 如何执行测试脚本
64 | [点击查看如何执行测试](https://github.com/radiateboy/automagic/wiki/Seleniumkeyword%E4%BB%8B%E7%BB%8D)
65 | ## 公众号
66 | 扫一扫关注公众号
67 |
68 | 
69 |
--------------------------------------------------------------------------------
/auto_auth/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/auto_auth/__init__.py
--------------------------------------------------------------------------------
/auto_auth/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/auto_auth/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AutoAuthConfig(AppConfig):
5 | name = 'auto_auth'
6 |
--------------------------------------------------------------------------------
/auto_auth/forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from django import forms
3 | from django.contrib.auth.models import User
4 | from django.contrib.auth.forms import UserCreationForm
5 | from django.utils.translation import ugettext_lazy as _
6 |
7 | from auto_auth.models import UserActivationKey
8 |
9 | class RegistrationForm(UserCreationForm):
10 | email = forms.EmailField()
11 |
12 | class Meta:
13 | model = User
14 | fields = ("username",)
15 |
16 | def clean_email(self):
17 | email = self.cleaned_data['email']
18 | try:
19 | User.objects.get(email=email)
20 | except User.DoesNotExist:
21 | return email
22 | raise forms.ValidationError(
23 | _("A user with that email already exists."))
24 |
25 | def save(self, commit=True):
26 | user = super(RegistrationForm, self).save(commit=False)
27 | user.email = self.cleaned_data['email']
28 | user.is_active = False
29 | user.set_password(self.cleaned_data["password1"])
30 |
31 | if User.objects.filter(is_superuser=True).count() == 0:
32 | user.is_superuser = True
33 |
34 | if commit:
35 | user.save()
36 | # initiate_user_with_default_setups(user)
37 | return user
38 |
39 | def set_activation_key(self):
40 | return UserActivationKey.set_random_key_for_user(user=self.instance)
41 |
--------------------------------------------------------------------------------
/auto_auth/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.2 on 2020-01-15 10:02
2 |
3 | from django.conf import settings
4 | import django.contrib.auth.models
5 | import django.contrib.auth.validators
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 | import django.utils.timezone
9 |
10 |
11 | class Migration(migrations.Migration):
12 |
13 | initial = True
14 |
15 | dependencies = [
16 | ('auth', '0011_update_proxy_permissions'),
17 | ]
18 |
19 | operations = [
20 | migrations.CreateModel(
21 | name='User',
22 | fields=[
23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24 | ('password', models.CharField(max_length=128, verbose_name='password')),
25 | ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
26 | ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
27 | ('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')),
28 | ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
29 | ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
30 | ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
31 | ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
32 | ('realname', models.CharField(blank=True, max_length=50, null=True, verbose_name='真实姓名')),
33 | ('mobile', models.CharField(blank=True, max_length=11, null=True, verbose_name='电话号码')),
34 | ('email', models.EmailField(max_length=255, unique=True, verbose_name='邮箱')),
35 | ('dept', models.CharField(choices=[('测试', '测试'), ('开发', '开发')], default='测试', max_length=100, verbose_name='部门')),
36 | ('is_active', models.BooleanField(default=True, verbose_name='激活状态')),
37 | ('is_admin', models.BooleanField(default=False, verbose_name='是否管理员')),
38 | ('testrailuser', models.CharField(blank=True, max_length=50, null=True, verbose_name='TestRail用户名')),
39 | ('testrailpass', models.CharField(blank=True, max_length=50, null=True, verbose_name='TestRail密码')),
40 | ('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')),
41 | ('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')),
42 | ],
43 | options={
44 | 'verbose_name': 'user',
45 | 'verbose_name_plural': 'users',
46 | 'abstract': False,
47 | },
48 | managers=[
49 | ('objects', django.contrib.auth.models.UserManager()),
50 | ],
51 | ),
52 | migrations.CreateModel(
53 | name='UserActivationKey',
54 | fields=[
55 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
56 | ('activation_key', models.CharField(blank=True, max_length=64, null=True)),
57 | ('key_expires', models.DateTimeField(blank=True, null=True)),
58 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
59 | ],
60 | ),
61 | ]
62 |
--------------------------------------------------------------------------------
/auto_auth/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/auto_auth/migrations/__init__.py
--------------------------------------------------------------------------------
/auto_auth/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import datetime
4 | import secrets
5 |
6 | from django.db import models
7 | from django.conf import settings
8 | from django.contrib.auth.models import BaseUserManager, AbstractUser
9 |
10 | class UserActivationKey(models.Model):
11 | user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
12 | activation_key = models.CharField(max_length=64, null=True, blank=True)
13 | key_expires = models.DateTimeField(null=True, blank=True)
14 |
15 | @classmethod
16 | def set_random_key_for_user(cls, user, force=False):
17 | activation_key = secrets.token_hex()
18 |
19 | # Create and save their profile
20 | user_activation_key, created = cls.objects.get_or_create(user=user)
21 | if created or force:
22 | user_activation_key.activation_key = activation_key
23 | user_activation_key.key_expires = datetime.datetime.today() + datetime.timedelta(7)
24 | user_activation_key.save()
25 |
26 | return user_activation_key
27 |
28 |
29 | class MyUserManager(BaseUserManager):
30 | # def current_time(self):
31 | # """get current time """
32 | # from datetime import datetime
33 | # return datetime.now().strftime("%Y-%m-%d")
34 |
35 | def create_user(self, username, email, password):
36 | """
37 | Creates and saves a User with the given email, date of
38 | birth and password.
39 | """
40 |
41 | if not username:
42 | raise ValueError('username is unique')
43 | user = self.model(username=username, email=self.normalize_email(email))
44 | user.set_password(password)
45 | user.save(using=self._db)
46 | return user
47 |
48 | def create_superuser(self, username, email, password):
49 | """
50 | Creates and saves a superuser with the given email, password.
51 | """
52 | user = self.create_user(username, email, password)
53 | user.is_admin = True
54 | user.is_staff = True
55 | user.save(using=self._db)
56 | return user
57 |
58 |
59 | class User(AbstractUser):
60 | Dept_Choice = (
61 | ('测试', '测试'),
62 | ('开发', '开发'),
63 | )
64 | realname = models.CharField(max_length=50, verbose_name="真实姓名", null=True, blank=True, editable=True)
65 | mobile = models.CharField(max_length=11, verbose_name="电话号码", null=True, blank=True, editable=True)
66 | email = models.EmailField(verbose_name='邮箱', max_length=255, unique=True)
67 | dept = models.CharField(verbose_name=u'部门', choices=Dept_Choice, default='测试', max_length=100)
68 | is_active = models.BooleanField(default=True, verbose_name='激活状态')
69 | is_admin = models.BooleanField(default=False, verbose_name='是否管理员')
70 | testrailuser = models.CharField(max_length=50, verbose_name="TestRail用户名", null=True, blank=True, editable=True)
71 | testrailpass = models.CharField(max_length=50, verbose_name="TestRail密码", null=True, blank=True, editable=True)
72 | def get_full_name(self):
73 | # The user is identified by their email address
74 | return self.username
75 |
76 | def get_short_name(self):
77 | # The user is identified by their email address
78 | return self.username
79 |
80 | def __unicode__(self): # __unicode__ on Python 2
81 | return self.username
82 |
83 | def has_perm(self, perm, obj=None):
84 | "Does the user have a specific permission?"
85 | # Simplest possible answer: Yes, always
86 | return True
87 |
88 | def has_module_perms(self, app_label):
89 | "Does the user have permissions to view the app `app_label`?"
90 | # Simplest possible answer: Yes, always
91 | return True
--------------------------------------------------------------------------------
/auto_auth/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/auto_auth/urls.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from django.conf.urls import url
4 | from django.urls import reverse_lazy
5 | from django.contrib.auth import views as contrib_auth_views
6 | from django.contrib.auth.decorators import login_required
7 | from auto_auth import views
8 |
9 | urlpatterns = [
10 | url(r'^(?P[\w.@+-]+)/profile/$', views.profile,
11 | name='auto-profile'),
12 |
13 | url(r'^register/$', views.register, name='auto-register'),
14 |
15 | url(r'^confirm/(?P[A-Za-z0-9\-]+)/$', views.confirm,
16 | name='auto-confirm'),
17 |
18 | url(r'^user/add/$', views.add_user, name='adduser'),
19 | url(r'^user/list/$', login_required(views.UserListIndex.as_view()), name='userlist'),
20 | url(r'^user/update/$', views.update_user, name='userupdate'),
21 | url(r'^user/del/(?P\d+)/$', views.del_user, name='userdel'),
22 | url(r'^setedit/user/$', views.set_edit_user, name='setedituser'),
23 |
24 | url(r'^login/$', views.LoginViewWithCustomTemplate.as_view(), name='auto-login'),
25 | url(r'^logout/$',
26 | contrib_auth_views.LogoutView.as_view(next_page=reverse_lazy('auto-login')),
27 | name='auto-logout'),
28 |
29 | url(r'^passwordreset/$', contrib_auth_views.PasswordResetView.as_view(),
30 | name='auto-password_reset'),
31 | url(r'^passwordreset/done/$', contrib_auth_views.PasswordResetDoneView.as_view(),
32 | name='password_reset_done'),
33 | url(r'^passwordreset/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$',
34 | contrib_auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
35 | url(r'^passwordreset/complete/$',
36 | contrib_auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
37 | ]
38 |
--------------------------------------------------------------------------------
/automatic/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | __version__ = '2.0'
3 |
4 | import pymysql
5 | pymysql.install_as_MySQLdb()
6 |
--------------------------------------------------------------------------------
/automatic/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for automatic project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'automatic.settings.common')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/automatic/element/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/element/__init__.py
--------------------------------------------------------------------------------
/automatic/element/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
5 | from automatic.element import models
6 |
7 |
8 | class ElementAdmin(admin.ModelAdmin):
9 | list_display = (id, 'descr', 'projectid', 'moduleid', 'locmode', 'location', 'createat', 'createtime', 'updateat', 'updatetime')
10 | search_fields = ('keyword', 'kwdescr')
11 |
12 |
13 | admin.site.register(models.Element, ElementAdmin)
--------------------------------------------------------------------------------
/automatic/element/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ElementConfig(AppConfig):
5 | name = 'automatic.element'
6 |
--------------------------------------------------------------------------------
/automatic/element/forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | """
3 | __author__ = 'Ray'
4 | mail:tsbc@vip.qq.com
5 | 2020-01-08
6 | """
7 | from django import forms
8 | from automatic.element.models import Element
9 | from django.forms import ModelForm, Textarea, Select, TextInput
10 |
11 |
12 | class FormElement(forms.ModelForm):
13 | class Meta:
14 | model = Element
15 | fields = ('descr','projectid','moduleid','locmode','location')
16 | widgets = {'locmode': Select(attrs={'class':'ak-left ac-aselect','required':''}),
17 | 'descr':TextInput(attrs={'class':'form-control','placeholder':'请输入元素描述','required':''}),
18 | 'location': TextInput(attrs={'class': 'form-control','placeholder':'(如:id_username)','required':''}),
19 | }
--------------------------------------------------------------------------------
/automatic/element/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.2 on 2020-01-15 10:02
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ('management', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='Element',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('descr', models.CharField(max_length=100)),
21 | ('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)),
22 | ('location', models.CharField(blank=True, max_length=200, null=True)),
23 | ('createtime', models.DateTimeField(auto_now_add=True)),
24 | ('createat', models.CharField(blank=True, max_length=32, null=True)),
25 | ('updatetime', models.DateTimeField(auto_now=True)),
26 | ('updateat', models.CharField(blank=True, max_length=32, null=True)),
27 | ('moduleid', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Module')),
28 | ('projectid', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Project')),
29 | ],
30 | ),
31 | ]
32 |
--------------------------------------------------------------------------------
/automatic/element/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/element/migrations/__init__.py
--------------------------------------------------------------------------------
/automatic/element/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | """
3 | __author__ = 'Ray'
4 | mail:tsbc@vip.qq.com
5 | 2020-01-06
6 | """
7 | from django.db import models
8 | from automatic.management.models import Project, Module
9 | # Create your models here.
10 |
11 | class Element(models.Model):
12 | Element_Choice = (
13 | ('id','id'),
14 | ('name','name'),
15 | ('css selector','css selector'),
16 | ('xpath','xpath'),
17 | ('class name','class name'),
18 | ('tag name','tag name'),
19 | ('link text','link text'),
20 | ('portial link_text','portial link text')
21 | )
22 | projectid = models.ForeignKey(Project, editable=True, on_delete=models.DO_NOTHING)
23 | moduleid = models.ForeignKey(Module, editable=True, on_delete=models.DO_NOTHING)
24 | descr = models.CharField(max_length=100, editable=True)
25 | locmode = models.CharField(max_length=32, choices=Element_Choice, null=True, blank=True, editable=True)
26 | location = models.CharField(max_length=200, null=True, blank=True, editable=True)
27 | createtime = models.DateTimeField(auto_now_add=True)
28 | createat = models.CharField(max_length=32, null=True, blank=True, editable=True)
29 | updatetime = models.DateTimeField(auto_now=True)
30 | updateat = models.CharField(max_length=32, null=True, blank=True, editable=True)
31 |
32 | def __unicode__(self):
33 | return self.descr
34 |
--------------------------------------------------------------------------------
/automatic/element/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/automatic/element/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from django.contrib.auth.decorators import login_required
3 | from automatic.element import views
4 |
5 | urlpatterns = [
6 | url(r'list/$', login_required(views.ElementListIndex.as_view()), name='elementlist'),
7 | url(r'add/$', views.add_element, name='elementadd'),
8 | url(r'update/$', views.update_element, name='elementupdate'),
9 | url(r'del/(?P\d+)/$', views.del_element, name='elementdel'),
10 | url(r'get/$', views.get_element, name='getelement'),
11 | url(r'setedit/$', views.set_edit_element, name='seteditelement'),
12 | ]
--------------------------------------------------------------------------------
/automatic/keywords/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/keywords/__init__.py
--------------------------------------------------------------------------------
/automatic/keywords/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
5 | from automatic.keywords import models
6 |
7 |
8 | class KeywordAdmin(admin.ModelAdmin):
9 | list_display = (id, 'keyword', 'kwdescr','createat', 'createtime', 'updateat', 'updatetime')
10 | search_fields = ('keyword', 'kwdescr')
11 |
12 |
13 | admin.site.register(models.Keyword, KeywordAdmin)
--------------------------------------------------------------------------------
/automatic/keywords/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class KeywordsConfig(AppConfig):
5 | name = 'automatic.keywords'
6 |
--------------------------------------------------------------------------------
/automatic/keywords/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.2 on 2020-01-15 10:02
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | initial = True
9 |
10 | dependencies = [
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='Keyword',
16 | fields=[
17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18 | ('productid', models.IntegerField(blank=True, null=True, verbose_name='所属产品')),
19 | ('keyword', models.CharField(max_length=32, unique=True)),
20 | ('kwdescr', models.TextField(blank=True, null=True)),
21 | ('createtime', models.DateTimeField(auto_now_add=True)),
22 | ('createat', models.CharField(blank=True, max_length=32, null=True)),
23 | ('updatetime', models.DateTimeField(auto_now=True)),
24 | ('updateat', models.CharField(blank=True, max_length=32, null=True)),
25 | ],
26 | options={
27 | 'ordering': ['productid'],
28 | },
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/automatic/keywords/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/keywords/migrations/__init__.py
--------------------------------------------------------------------------------
/automatic/keywords/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | """
3 | __author__ = 'Ray'
4 | mail:tsbc@vip.qq.com
5 | 2020-01-06
6 | """
7 | from django.db import models
8 | # Create your models here.
9 |
10 |
11 | class Keyword(models.Model):
12 | productid = models.IntegerField(verbose_name='所属产品', null=True, blank=True, editable=True)
13 | keyword = models.CharField(max_length=32, unique=True)
14 | kwdescr = models.TextField(null=True,blank=True,editable=True)
15 | createtime = models.DateTimeField(auto_now_add=True)
16 | createat = models.CharField(max_length=32, null=True, blank=True, editable=True)
17 | updatetime = models.DateTimeField(auto_now=True)
18 | updateat = models.CharField(max_length=32, null=True, blank=True, editable=True)
19 |
20 | def __unicode__(self):
21 | return self.keyword
22 |
23 | class Meta:
24 | ordering = ["productid"]
--------------------------------------------------------------------------------
/automatic/keywords/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/automatic/keywords/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from django.contrib.auth.decorators import login_required
3 | from automatic.keywords import views
4 |
5 | urlpatterns = [
6 | url(r'list/$', login_required(views.KeyWordListIndex.as_view()), name='keywordlist'),
7 | url(r'add/$', views.add_keyword, name='keywordadd'),
8 | url(r'update/$', views.update_keyword, name='keywordupdate'),
9 | url(r'del/(?P\d+)/$', views.del_keyword, name='keyworddel'),
10 | url(r'get/$', views.get_keyword, name='getkeyword'),
11 | url(r'setedit/$', views.set_edit_keyword, name='seteditelement'),
12 | ]
--------------------------------------------------------------------------------
/automatic/keywords/views.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | """
3 | __author__ = 'Ray'
4 | mail:tsbc@vip.qq.com
5 | 2020-01-08
6 | """
7 | import json
8 |
9 | from django.utils import timezone
10 | from django.contrib.auth.decorators import login_required
11 | from django.shortcuts import render, redirect, get_object_or_404
12 | from django.http import HttpResponse,HttpResponseRedirect
13 | from django.views.decorators.csrf import csrf_exempt
14 |
15 | from automatic.element.forms import *
16 | from django.views.generic import ListView
17 | from automatic.element.models import *
18 | from django.db.models import Q
19 | from django.urls import reverse
20 | from automatic.management.models import Product, Project, UserAndProduct
21 | from automatic.keywords.models import Keyword
22 |
23 |
24 | class KeyWordListIndex(ListView):
25 | context_object_name = 'keywordlist'
26 | template_name = 'keywords/keyword.html'
27 | paginate_by = 10
28 | keywordsum = 0
29 | model = Keyword
30 | http_method_names = [u'get']
31 |
32 | def get_queryset(self):
33 | keywordlist = Keyword.objects.all().order_by('-pk')
34 | keyword = self.request.GET.get('keyword')
35 | if keyword:
36 | keywordlist = keywordlist.filter(Q(keyword__icontains=keyword)|Q(kwdescr__icontains=keyword))
37 | self.keywordsum = len(keywordlist)
38 | return keywordlist
39 |
40 | def get_context_data(self, **kwargs):
41 | context = super(KeyWordListIndex,self).get_context_data(**kwargs)
42 | context['userandproduct'] = UserAndProduct.objects.all()
43 | context['productlist'] = Product.objects.all()
44 | context['keywordsum'] = self.keywordsum
45 | return context
46 |
47 |
48 | @login_required()
49 | def add_keyword(request):
50 | if request.method == 'POST':
51 | name = request.POST['keyword']
52 | descr = request.POST['kwdescr']
53 | productid = request.POST['productid']
54 | createat = request.user.username
55 | updateat = request.user.username
56 | keyword = Keyword(productid=productid, keyword=name, kwdescr=descr, createat=createat, updateat=updateat)
57 | try:
58 | keyword.save()
59 | except Exception as e:
60 | return HttpResponse(e)
61 | return HttpResponse('添加关键字成功。')
62 | else:
63 | return HttpResponse('添加关键字失败。')
64 |
65 |
66 | @csrf_exempt
67 | @login_required()
68 | def update_keyword(request):
69 | if request.method == 'POST':
70 | id = request.POST['keywordid']
71 | name = request.POST['keyword']
72 | descr = request.POST['kwdescr']
73 | productid = request.POST['productname']
74 | updateat = request.user.username
75 | updatetime = timezone.now()
76 | k = Keyword.objects.filter(id=int(id))
77 | k.update(productid=productid, keyword=name, kwdescr=descr, updateat=updateat, updatetime=updatetime)
78 | return HttpResponse('修改关键字成功。')
79 | else:
80 | return HttpResponse('修改关键字失败。')
81 |
82 |
83 | @login_required()
84 | def del_keyword(request, id):
85 | keyword = get_object_or_404(Keyword, pk=int(id))
86 | keyword.delete()
87 | return HttpResponseRedirect(reverse('keywordlist'))
88 |
89 |
90 | @login_required()
91 | def get_keyword(request):
92 | keywordlist = []
93 | productid = request.GET['productid']
94 | kwlist = Keyword.objects.filter(Q(productid=productid)|Q(productid=0))
95 | for i in kwlist:
96 | keywordinfo = {}
97 | keywordinfo['key'] = i.id
98 | keywordinfo['kwdescr'] = i.kwdescr
99 | keywordinfo['keyword'] = i.keyword
100 | keywordinfo['productid'] = i.productid
101 | keywordlist.append(keywordinfo)
102 | return HttpResponse(json.dumps(keywordlist))
103 |
104 |
105 | @login_required()
106 | def set_edit_keyword(request):
107 | keywordid = request.GET['keywordid']
108 | kw = Keyword.objects.get(pk=keywordid)
109 | keywordinfo = {}
110 | keywordinfo['id'] = kw.pk
111 | keywordinfo['descr'] = kw.kwdescr
112 | keywordinfo['name'] = kw.keyword
113 | keywordinfo['productid'] = kw.productid
114 | keywordlist = [keywordinfo]
115 | return HttpResponse(json.dumps(keywordlist))
--------------------------------------------------------------------------------
/automatic/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/management/__init__.py
--------------------------------------------------------------------------------
/automatic/management/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
5 | from automatic.management import models
6 |
7 |
8 | class ProductAdmin(admin.ModelAdmin):
9 | list_display = (id, 'name', 'isenabled', 'descr','createat', 'createtime', 'updateat', 'updatetime')
10 | search_fields = ('name','descr')
11 |
12 |
13 | class ProjectAdmin(admin.ModelAdmin):
14 | list_display = (id, 'name', 'isenabled','version','descr','createat', 'createtime', 'updateat', 'updatetime')
15 | search_fields = ('name','descr','version')
16 |
17 |
18 | class ModuleAdmin(admin.ModelAdmin):
19 | list_display = (id, 'name', 'isenabled', 'createat', 'createtime', 'updateat', 'updatetime')
20 | search_fields = ('name',)
21 |
22 |
23 | admin.site.register(models.Product, ProductAdmin)
24 | admin.site.register(models.Project, ProjectAdmin)
25 | admin.site.register(models.Module, ModuleAdmin)
--------------------------------------------------------------------------------
/automatic/management/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ManagementConfig(AppConfig):
5 | name = 'automatic.management'
6 |
--------------------------------------------------------------------------------
/automatic/management/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.2 on 2020-01-15 10:02
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | initial = True
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name='Product',
19 | fields=[
20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21 | ('name', models.CharField(max_length=32, unique=True, verbose_name='产品名称')),
22 | ('isenabled', models.BooleanField(blank=True, default=True, verbose_name='产品状态')),
23 | ('descr', models.TextField(blank=True, null=True, verbose_name='产品描述')),
24 | ('createtime', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
25 | ('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
26 | ('updatetime', models.DateTimeField(auto_now=True, null=True, verbose_name='更新时间')),
27 | ('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
28 | ('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
29 | ],
30 | options={
31 | 'ordering': ['-sortby'],
32 | },
33 | ),
34 | migrations.CreateModel(
35 | name='UserAndProduct',
36 | fields=[
37 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
38 | ('productname', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='management.Product')),
39 | ('username', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
40 | ],
41 | ),
42 | migrations.CreateModel(
43 | name='Project',
44 | fields=[
45 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
46 | ('name', models.CharField(max_length=32, unique=True, verbose_name='项目名称')),
47 | ('version', models.CharField(blank=True, max_length=32, null=True, verbose_name='版本')),
48 | ('isenabled', models.BooleanField(default=True, verbose_name='状态')),
49 | ('descr', models.TextField(blank=True, null=True, verbose_name='项目描述')),
50 | ('createtime', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
51 | ('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
52 | ('updatetime', models.DateTimeField(auto_now=True, null=True, verbose_name='更新时间')),
53 | ('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
54 | ('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
55 | ('productid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='management.Product', verbose_name='产品名称')),
56 | ],
57 | options={
58 | 'ordering': ['-sortby'],
59 | },
60 | ),
61 | migrations.CreateModel(
62 | name='Module',
63 | fields=[
64 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
65 | ('name', models.CharField(max_length=32, verbose_name='模块名称')),
66 | ('isenabled', models.BooleanField(default=True, verbose_name='状态')),
67 | ('createtime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
68 | ('createat', models.CharField(blank=True, max_length=32, null=True, verbose_name='创建者')),
69 | ('updatetime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
70 | ('updateat', models.CharField(blank=True, max_length=32, null=True, verbose_name='更新者')),
71 | ('sortby', models.IntegerField(blank=True, default=0, null=True, verbose_name='排序')),
72 | ('projectid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='management.Project', verbose_name='所属项目')),
73 | ],
74 | options={
75 | 'ordering': ['-sortby'],
76 | },
77 | ),
78 | ]
79 |
--------------------------------------------------------------------------------
/automatic/management/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/management/migrations/__init__.py
--------------------------------------------------------------------------------
/automatic/management/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | """
3 | __author__ = 'Ray'
4 | mail:tsbc@vip.qq.com
5 | 2020-01-06
6 | """
7 | from __future__ import unicode_literals
8 |
9 | import datetime
10 | from django.db import models
11 | from auto_auth.models import User
12 | # Create your models here.
13 |
14 |
15 | class Product(models.Model):
16 | name = models.CharField(max_length=32, verbose_name='产品名称', unique=True)
17 | # version = models.CharField(max_length=32)
18 | isenabled = models.BooleanField(default=True, blank=True, verbose_name='产品状态')
19 | descr = models.TextField(null=True, blank=True, verbose_name='产品描述')
20 | createtime = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name='创建时间')
21 | createat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='创建者')
22 | updatetime = models.DateTimeField(auto_now=True,null=True, blank=True, verbose_name='更新时间')
23 | updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
24 | sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
25 |
26 | def __unicode__(self):
27 | return self.name
28 |
29 | def save(self, *args, **kwargs):
30 | if not self.id:
31 | self.createtime = datetime.datetime.now()
32 | self.updatetime = datetime.datetime.now()
33 |
34 | super(Product, self).save(*args, **kwargs)
35 |
36 | class Meta:
37 | ordering = ["-sortby"]
38 |
39 |
40 | class Project(models.Model):
41 | productid = models.ForeignKey(Product, verbose_name='产品名称', on_delete=models.CASCADE)
42 | name = models.CharField(max_length=32, unique=True, verbose_name='项目名称')
43 | version = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='版本')
44 | isenabled = models.BooleanField(default=True, verbose_name='状态')
45 | descr = models.TextField(null=True, blank=True, editable=True,verbose_name='项目描述')
46 | createtime = models.DateTimeField(auto_now_add=True, null=True, blank=True, editable=True,verbose_name='创建时间')
47 | createat = models.CharField( max_length=32, null=True, blank=True, editable=True, verbose_name='创建者')
48 | updatetime = models.DateTimeField(auto_now=True,null=True, blank=True, verbose_name='更新时间')
49 | updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
50 | sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
51 |
52 | def __unicode__(self):
53 | return self.name
54 |
55 | class Meta:
56 | ordering = ["-sortby"]
57 |
58 |
59 | class Module(models.Model):
60 | projectid = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.CASCADE)
61 | name = models.CharField(max_length=32, verbose_name='模块名称')
62 | isenabled = models.BooleanField(default=True, verbose_name='状态')
63 | createtime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
64 | createat = models.CharField(max_length=32 ,null=True, blank=True, editable=True, verbose_name='创建者')
65 | updatetime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
66 | updateat = models.CharField(max_length=32, null=True, blank=True, editable=True, verbose_name='更新者')
67 | sortby = models.IntegerField(null=True, blank=True, editable=True, default=0, verbose_name='排序')
68 |
69 | def __unicode__(self):
70 | return self.name
71 |
72 | class Meta:
73 | ordering = ["-sortby"]
74 |
75 | class UserAndProduct(models.Model):
76 | username = models.ForeignKey(User, on_delete=models.DO_NOTHING)
77 | productname = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/automatic/management/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/automatic/management/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from django.contrib.auth.decorators import login_required
3 | from automatic.management import views
4 |
5 | urlpatterns = [
6 | url(r'^product/add/$', views.add_product, name='productadd'),
7 | url(r'^product/view/(?P\d+)', views.view_product, name='productview'),
8 | url(r'^product/list/$', login_required(views.ProductListIndex.as_view()), name='productlist'),
9 | url(r'^product/update/$', views.update_product, name='productupdate'),
10 | url(r'^product/del/(?P\d+)/$', views.del_product, name='productdel'),
11 | url(r'^project/add/$', views.add_project, name='projectadd'),
12 | url(r'^project/list/$', login_required(views.ProjectListIndex.as_view()), name='projectlist'),
13 | url(r'^project/view/(?P\d+)', views.view_project, name='projectview'),
14 | url(r'^project/update/$', views.update_project, name='projectupdate'),
15 | url(r'^project/del/(?P\d+)/$', views.del_project, name='projectdel'),
16 | url(r'^module/add/$', views.add_module, name='moduleadd'),
17 | # url(r'^module/list/$', login_required(views.ModuleListIndex.as_view()), name='modulelist'),
18 | url(r'^module/update/$', views.update_module, name='moduleupdate'),
19 | url(r'^module/del/(?P\d+)/$', views.del_module, name='moduledel'),
20 | url(r'^get/project/$', views.get_project, name='getproject'),
21 | url(r'^get/module/$', views.get_module, name='getmodule'),
22 | url(r'^get/connecteduser/$', views.get_connected_user, name='getconnecteduser'),
23 | url(r'^product/user/$', views.product_user, name='productuser'),
24 | url(r'^get/moduleList/$', views.get_module_list, name='getmodulelist'),
25 | url(r'^setedit/product/$', views.set_edit_product, name='seteditproduct'),
26 | url(r'^setedit/project/$', views.set_edit_project, name='seteditproject'),
27 | url(r'^setedit/module/$', views.set_edit_module, name='seteditmodule'),
28 | url(r'^syslog/home/$', views.page_syslog, name='toolsyslog'),
29 | url(r'^snmp/home/$', views.comingsoon, name='toolsnmp'),
30 | ]
--------------------------------------------------------------------------------
/automatic/settings/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/settings/__init__.py
--------------------------------------------------------------------------------
/automatic/signals.py:
--------------------------------------------------------------------------------
1 | from django.dispatch import Signal
2 |
3 | USER_REGISTERED_SIGNAL = Signal(providing_args=['user'])
--------------------------------------------------------------------------------
/automatic/static/css/bootstrapValidator.css:
--------------------------------------------------------------------------------
1 | /**
2 | * BootstrapValidator (http://bootstrapvalidator.com)
3 | * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
4 | *
5 | * @author http://twitter.com/nghuuphuoc
6 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc
7 | * @license MIT
8 | */
9 |
10 | .bv-form .help-block {
11 | margin-bottom: 0;
12 | }
13 | .bv-form .tooltip-inner {
14 | text-align: left;
15 | }
16 | .nav-tabs li.bv-tab-success > a {
17 | color: #3c763d;
18 | }
19 | .nav-tabs li.bv-tab-error > a {
20 | color: #a94442;
21 | }
22 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/font/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/font/FontAwesome.otf
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/font/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/font/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/font/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/font/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/font/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/font/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/css/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/bootstrap.less:
--------------------------------------------------------------------------------
1 | /* BOOTSTRAP SPECIFIC CLASSES
2 | * -------------------------- */
3 |
4 | /* Bootstrap 2.0 sprites.less reset */
5 | [class^="icon-"],
6 | [class*=" icon-"] {
7 | display: inline;
8 | width: auto;
9 | height: auto;
10 | line-height: normal;
11 | vertical-align: baseline;
12 | background-image: none;
13 | background-position: 0% 0%;
14 | background-repeat: repeat;
15 | margin-top: 0;
16 | }
17 |
18 | /* more sprites.less reset */
19 | .icon-white,
20 | .nav-pills > .active > a > [class^="icon-"],
21 | .nav-pills > .active > a > [class*=" icon-"],
22 | .nav-list > .active > a > [class^="icon-"],
23 | .nav-list > .active > a > [class*=" icon-"],
24 | .navbar-inverse .nav > .active > a > [class^="icon-"],
25 | .navbar-inverse .nav > .active > a > [class*=" icon-"],
26 | .dropdown-menu > li > a:hover > [class^="icon-"],
27 | .dropdown-menu > li > a:hover > [class*=" icon-"],
28 | .dropdown-menu > .active > a > [class^="icon-"],
29 | .dropdown-menu > .active > a > [class*=" icon-"],
30 | .dropdown-submenu:hover > a > [class^="icon-"],
31 | .dropdown-submenu:hover > a > [class*=" icon-"] {
32 | background-image: none;
33 | }
34 |
35 |
36 | /* keeps Bootstrap styles with and without icons the same */
37 | .btn, .nav {
38 | [class^="icon-"],
39 | [class*=" icon-"] {
40 | // display: inline;
41 | &.icon-large { line-height: .9em; }
42 | &.icon-spin { display: inline-block; }
43 | }
44 | }
45 | .nav-tabs, .nav-pills {
46 | [class^="icon-"],
47 | [class*=" icon-"] {
48 | &, &.icon-large { line-height: .9em; }
49 | }
50 | }
51 | .btn {
52 | [class^="icon-"],
53 | [class*=" icon-"] {
54 | &.pull-left, &.pull-right {
55 | &.icon-2x { margin-top: .18em; }
56 | }
57 | &.icon-spin.icon-large { line-height: .8em; }
58 | }
59 | }
60 | .btn.btn-small {
61 | [class^="icon-"],
62 | [class*=" icon-"] {
63 | &.pull-left, &.pull-right {
64 | &.icon-2x { margin-top: .25em; }
65 | }
66 | }
67 | }
68 | .btn.btn-large {
69 | [class^="icon-"],
70 | [class*=" icon-"] {
71 | margin-top: 0; // overrides bootstrap default
72 | &.pull-left, &.pull-right {
73 | &.icon-2x { margin-top: .05em; }
74 | }
75 | &.pull-left.icon-2x { margin-right: .2em; }
76 | &.pull-right.icon-2x { margin-left: .2em; }
77 | }
78 | }
79 |
80 | /* Fixes alignment in nav lists */
81 | .nav-list [class^="icon-"],
82 | .nav-list [class*=" icon-"] {
83 | line-height: inherit;
84 | }
85 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .pull-right { float: right; }
11 | .pull-left { float: left; }
12 |
13 | .@{fa-css-prefix} {
14 | &.pull-left { margin-right: .3em; }
15 | &.pull-right { margin-left: .3em; }
16 | }
17 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | /* FONT AWESOME CORE
2 | * -------------------------- */
3 |
4 | [class^="icon-"],
5 | [class*=" icon-"] {
6 | .icon-FontAwesome();
7 | }
8 |
9 | [class^="icon-"]:before,
10 | [class*=" icon-"]:before {
11 | text-decoration: inherit;
12 | display: inline-block;
13 | speak: none;
14 | }
15 |
16 | /* makes the font 33% larger relative to the icon container */
17 | .icon-large:before {
18 | vertical-align: -10%;
19 | font-size: 4/3em;
20 | }
21 |
22 | /* makes sure icons active on rollover in links */
23 | a {
24 | [class^="icon-"],
25 | [class*=" icon-"] {
26 | display: inline;
27 | }
28 | }
29 |
30 | /* increased font size for icon-large */
31 | [class^="icon-"],
32 | [class*=" icon-"] {
33 | &.icon-fixed-width {
34 | display: inline-block;
35 | width: 16/14em;
36 | text-align: right;
37 | padding-right: 4/14em;
38 | &.icon-large {
39 | width: 20/14em;
40 | }
41 | }
42 | }
43 |
44 | .icons-ul {
45 | margin-left: @icons-li-width;
46 | list-style-type: none;
47 |
48 | > li { position: relative; }
49 |
50 | .icon-li {
51 | position: absolute;
52 | left: -@icons-li-width;
53 | width: @icons-li-width;
54 | text-align: center;
55 | line-height: inherit;
56 | }
57 | }
58 |
59 | // allows usage of the hide class directly on font awesome icons
60 | [class^="icon-"],
61 | [class*=" icon-"] {
62 | &.hide {
63 | display: none;
64 | }
65 | }
66 |
67 | .icon-muted { color: @iconMuted; }
68 | .icon-light { color: @iconLight; }
69 | .icon-dark { color: @iconDark; }
70 |
71 | // Icon Borders
72 | // -------------------------
73 |
74 | .icon-border {
75 | border: solid 1px @borderColor;
76 | padding: .2em .25em .15em;
77 | .border-radius(3px);
78 | }
79 |
80 | // Icon Sizes
81 | // -------------------------
82 |
83 | .icon-2x {
84 | font-size: 2em;
85 | &.icon-border {
86 | border-width: 2px;
87 | .border-radius(4px);
88 | }
89 | }
90 | .icon-3x {
91 | font-size: 3em;
92 | &.icon-border {
93 | border-width: 3px;
94 | .border-radius(5px);
95 | }
96 | }
97 | .icon-4x {
98 | font-size: 4em;
99 | &.icon-border {
100 | border-width: 4px;
101 | .border-radius(6px);
102 | }
103 | }
104 |
105 | .icon-5x {
106 | font-size: 5em;
107 | &.icon-border {
108 | border-width: 5px;
109 | .border-radius(7px);
110 | }
111 | }
112 |
113 |
114 | // Floats & Margins
115 | // -------------------------
116 |
117 | // Quick floats
118 | .pull-right { float: right; }
119 | .pull-left { float: left; }
120 |
121 | [class^="icon-"],
122 | [class*=" icon-"] {
123 | &.pull-left {
124 | margin-right: .3em;
125 | }
126 | &.pull-right {
127 | margin-left: .3em;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/extras.less:
--------------------------------------------------------------------------------
1 | /* EXTRAS
2 | * -------------------------- */
3 |
4 | /* Stacked and layered icon */
5 | .icon-stack();
6 |
7 | /* Animated rotating icon */
8 | .icon-spin {
9 | display: inline-block;
10 | -moz-animation: spin 2s infinite linear;
11 | -o-animation: spin 2s infinite linear;
12 | -webkit-animation: spin 2s infinite linear;
13 | animation: spin 2s infinite linear;
14 | }
15 |
16 | /* Prevent stack and spinners from being taken inline when inside a link */
17 | a .icon-stack,
18 | a .icon-spin {
19 | display: inline-block;
20 | text-decoration: none;
21 | }
22 |
23 | @-moz-keyframes spin {
24 | 0% { -moz-transform: rotate(0deg); }
25 | 100% { -moz-transform: rotate(359deg); }
26 | }
27 | @-webkit-keyframes spin {
28 | 0% { -webkit-transform: rotate(0deg); }
29 | 100% { -webkit-transform: rotate(359deg); }
30 | }
31 | @-o-keyframes spin {
32 | 0% { -o-transform: rotate(0deg); }
33 | 100% { -o-transform: rotate(359deg); }
34 | }
35 | @-ms-keyframes spin {
36 | 0% { -ms-transform: rotate(0deg); }
37 | 100% { -ms-transform: rotate(359deg); }
38 | }
39 | @keyframes spin {
40 | 0% { transform: rotate(0deg); }
41 | 100% { transform: rotate(359deg); }
42 | }
43 |
44 | /* Icon rotations and mirroring */
45 | .icon-rotate-90:before {
46 | -webkit-transform: rotate(90deg);
47 | -moz-transform: rotate(90deg);
48 | -ms-transform: rotate(90deg);
49 | -o-transform: rotate(90deg);
50 | transform: rotate(90deg);
51 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
52 | }
53 |
54 | .icon-rotate-180:before {
55 | -webkit-transform: rotate(180deg);
56 | -moz-transform: rotate(180deg);
57 | -ms-transform: rotate(180deg);
58 | -o-transform: rotate(180deg);
59 | transform: rotate(180deg);
60 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
61 | }
62 |
63 | .icon-rotate-270:before {
64 | -webkit-transform: rotate(270deg);
65 | -moz-transform: rotate(270deg);
66 | -ms-transform: rotate(270deg);
67 | -o-transform: rotate(270deg);
68 | transform: rotate(270deg);
69 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
70 | }
71 |
72 | .icon-flip-horizontal:before {
73 | -webkit-transform: scale(-1, 1);
74 | -moz-transform: scale(-1, 1);
75 | -ms-transform: scale(-1, 1);
76 | -o-transform: scale(-1, 1);
77 | transform: scale(-1, 1);
78 | }
79 |
80 | .icon-flip-vertical:before {
81 | -webkit-transform: scale(1, -1);
82 | -moz-transform: scale(1, -1);
83 | -ms-transform: scale(1, -1);
84 | -o-transform: scale(1, -1);
85 | transform: scale(1, -1);
86 | }
87 |
88 | /* ensure rotation occurs inside anchor tags */
89 | a {
90 | .icon-rotate-90, .icon-rotate-180, .icon-rotate-270, .icon-flip-horizontal, .icon-flip-vertical {
91 | &:before { display: inline-block; }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 3.2.1
3 | * the iconic font designed for Bootstrap
4 | * ------------------------------------------------------------------------------
5 | * The full suite of pictographic icons, examples, and documentation can be
6 | * found at http://fontawesome.io. Stay up to date on Twitter at
7 | * http://twitter.com/fontawesome.
8 | *
9 | * License
10 | * ------------------------------------------------------------------------------
11 | * - The Font Awesome font is licensed under SIL OFL 1.1 -
12 | * http://scripts.sil.org/OFL
13 | * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License -
14 | * http://opensource.org/licenses/mit-license.html
15 | * - Font Awesome documentation licensed under CC BY 3.0 -
16 | * http://creativecommons.org/licenses/by/3.0/
17 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
18 | * "Font Awesome by Dave Gandy - http://fontawesome.io"
19 | *
20 | * Author - Dave Gandy
21 | * ------------------------------------------------------------------------------
22 | * Email: dave@fontawesome.io
23 | * Twitter: http://twitter.com/byscuits
24 | * Work: Lead Product Designer @ Kyruus - http://kyruus.com
25 | */
26 |
27 | @import "variables.less";
28 | @import "mixins.less";
29 | @import "path.less";
30 | @import "core.less";
31 | @import "bootstrap.less";
32 | @import "extras.less";
33 | @import "icons.less";
34 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .icon(@icon) {
5 | .icon-FontAwesome();
6 | content: @icon;
7 | }
8 |
9 | .icon-FontAwesome() {
10 | font-family: FontAwesome;
11 | font-weight: normal;
12 | font-style: normal;
13 | text-decoration: inherit;
14 | -webkit-font-smoothing: antialiased;
15 | *margin-right: .3em; // fixes ie7 issues
16 | }
17 |
18 | .border-radius(@radius) {
19 | -webkit-border-radius: @radius;
20 | -moz-border-radius: @radius;
21 | border-radius: @radius;
22 | }
23 |
24 | .icon-stack(@width: 2em, @height: 2em, @top-font-size: 1em, @base-font-size: 2em) {
25 | .icon-stack {
26 | position: relative;
27 | display: inline-block;
28 | width: @width;
29 | height: @height;
30 | line-height: @width;
31 | vertical-align: -35%;
32 | [class^="icon-"],
33 | [class*=" icon-"] {
34 | display: block;
35 | text-align: center;
36 | position: absolute;
37 | width: 100%;
38 | height: 100%;
39 | font-size: @top-font-size;
40 | line-height: inherit;
41 | *line-height: @height;
42 | }
43 | .icon-stack-base {
44 | font-size: @base-font-size;
45 | *line-height: @height / @base-font-size;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=@{FontAwesomeVersion}');
7 | src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=@{FontAwesomeVersion}') format('embedded-opentype'),
8 | url('@{FontAwesomePath}/fontawesome-webfont.woff?v=@{FontAwesomeVersion}') format('woff'),
9 | url('@{FontAwesomePath}/fontawesome-webfont.ttf?v=@{FontAwesomeVersion}') format('truetype'),
10 | url('@{FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular?v=@{FontAwesomeVersion}') format('svg');
11 | // src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
12 | font-weight: normal;
13 | font-style: normal;
14 | }
15 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_bootstrap.scss:
--------------------------------------------------------------------------------
1 | /* BOOTSTRAP SPECIFIC CLASSES
2 | * -------------------------- */
3 |
4 | /* Bootstrap 2.0 sprites.less reset */
5 | [class^="icon-"],
6 | [class*=" icon-"] {
7 | display: inline;
8 | width: auto;
9 | height: auto;
10 | line-height: normal;
11 | vertical-align: baseline;
12 | background-image: none;
13 | background-position: 0% 0%;
14 | background-repeat: repeat;
15 | margin-top: 0;
16 | }
17 |
18 | /* more sprites.less reset */
19 | .icon-white,
20 | .nav-pills > .active > a > [class^="icon-"],
21 | .nav-pills > .active > a > [class*=" icon-"],
22 | .nav-list > .active > a > [class^="icon-"],
23 | .nav-list > .active > a > [class*=" icon-"],
24 | .navbar-inverse .nav > .active > a > [class^="icon-"],
25 | .navbar-inverse .nav > .active > a > [class*=" icon-"],
26 | .dropdown-menu > li > a:hover > [class^="icon-"],
27 | .dropdown-menu > li > a:hover > [class*=" icon-"],
28 | .dropdown-menu > .active > a > [class^="icon-"],
29 | .dropdown-menu > .active > a > [class*=" icon-"],
30 | .dropdown-submenu:hover > a > [class^="icon-"],
31 | .dropdown-submenu:hover > a > [class*=" icon-"] {
32 | background-image: none;
33 | }
34 |
35 |
36 | /* keeps Bootstrap styles with and without icons the same */
37 | .btn, .nav {
38 | [class^="icon-"],
39 | [class*=" icon-"] {
40 | // display: inline;
41 | &.icon-large { line-height: .9em; }
42 | &.icon-spin { display: inline-block; }
43 | }
44 | }
45 | .nav-tabs, .nav-pills {
46 | [class^="icon-"],
47 | [class*=" icon-"] {
48 | &, &.icon-large { line-height: .9em; }
49 | }
50 | }
51 | .btn {
52 | [class^="icon-"],
53 | [class*=" icon-"] {
54 | &.pull-left, &.pull-right {
55 | &.icon-2x { margin-top: .18em; }
56 | }
57 | &.icon-spin.icon-large { line-height: .8em; }
58 | }
59 | }
60 | .btn.btn-small {
61 | [class^="icon-"],
62 | [class*=" icon-"] {
63 | &.pull-left, &.pull-right {
64 | &.icon-2x { margin-top: .25em; }
65 | }
66 | }
67 | }
68 | .btn.btn-large {
69 | [class^="icon-"],
70 | [class*=" icon-"] {
71 | margin-top: 0; // overrides bootstrap default
72 | &.pull-left, &.pull-right {
73 | &.icon-2x { margin-top: .05em; }
74 | }
75 | &.pull-left.icon-2x { margin-right: .2em; }
76 | &.pull-right.icon-2x { margin-left: .2em; }
77 | }
78 | }
79 |
80 | /* Fixes alignment in nav lists */
81 | .nav-list [class^="icon-"],
82 | .nav-list [class*=" icon-"] {
83 | line-height: inherit;
84 | }
85 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .pull-right { float: right; }
11 | .pull-left { float: left; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.pull-left { margin-right: .3em; }
15 | &.pull-right { margin-left: .3em; }
16 | }
17 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | /* FONT AWESOME CORE
2 | * -------------------------- */
3 |
4 | [class^="icon-"],
5 | [class*=" icon-"] {
6 | @include icon-FontAwesome();
7 | }
8 |
9 | [class^="icon-"]:before,
10 | [class*=" icon-"]:before {
11 | text-decoration: inherit;
12 | display: inline-block;
13 | speak: none;
14 | }
15 |
16 | /* makes the font 33% larger relative to the icon container */
17 | .icon-large:before {
18 | vertical-align: -10%;
19 | font-size: (4em/3);
20 | }
21 |
22 | /* makes sure icons active on rollover in links */
23 | a {
24 | [class^="icon-"],
25 | [class*=" icon-"] {
26 | display: inline;
27 | }
28 | }
29 |
30 | /* increased font size for icon-large */
31 | [class^="icon-"],
32 | [class*=" icon-"] {
33 | &.icon-fixed-width {
34 | display: inline-block;
35 | width: (16em/14);
36 | text-align: right;
37 | padding-right: (4em/14);
38 | &.icon-large {
39 | width: (20em/14);
40 | }
41 | }
42 | }
43 |
44 | .icons-ul {
45 | margin-left: $icons-li-width;
46 | list-style-type: none;
47 |
48 | > li { position: relative; }
49 |
50 | .icon-li {
51 | position: absolute;
52 | left: -$icons-li-width;
53 | width: $icons-li-width;
54 | text-align: center;
55 | line-height: inherit;
56 | }
57 | }
58 |
59 | // allows usage of the hide class directly on font awesome icons
60 | [class^="icon-"],
61 | [class*=" icon-"] {
62 | &.hide {
63 | display: none;
64 | }
65 | }
66 |
67 | .icon-muted { color: $iconMuted; }
68 | .icon-light { color: $iconLight; }
69 | .icon-dark { color: $iconDark; }
70 |
71 | // Icon Borders
72 | // -------------------------
73 |
74 | .icon-border {
75 | border: solid 1px $borderColor;
76 | padding: .2em .25em .15em;
77 | @include border-radius(3px);
78 | }
79 |
80 | // Icon Sizes
81 | // -------------------------
82 |
83 | .icon-2x {
84 | font-size: 2em;
85 | &.icon-border {
86 | border-width: 2px;
87 | @include border-radius(4px);
88 | }
89 | }
90 | .icon-3x {
91 | font-size: 3em;
92 | &.icon-border {
93 | border-width: 3px;
94 | @include border-radius(5px);
95 | }
96 | }
97 | .icon-4x {
98 | font-size: 4em;
99 | &.icon-border {
100 | border-width: 4px;
101 | @include border-radius(6px);
102 | }
103 | }
104 |
105 | .icon-5x {
106 | font-size: 5em;
107 | &.icon-border {
108 | border-width: 5px;
109 | @include border-radius(7px);
110 | }
111 | }
112 |
113 |
114 | // Floats & Margins
115 | // -------------------------
116 |
117 | // Quick floats
118 | .pull-right { float: right; }
119 | .pull-left { float: left; }
120 |
121 | [class^="icon-"],
122 | [class*=" icon-"] {
123 | &.pull-left {
124 | margin-right: .3em;
125 | }
126 | &.pull-right {
127 | margin-left: .3em;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_extras.scss:
--------------------------------------------------------------------------------
1 | /* EXTRAS
2 | * -------------------------- */
3 |
4 | /* Stacked and layered icon */
5 | @include icon-stack();
6 |
7 | /* Animated rotating icon */
8 | .icon-spin {
9 | display: inline-block;
10 | -moz-animation: spin 2s infinite linear;
11 | -o-animation: spin 2s infinite linear;
12 | -webkit-animation: spin 2s infinite linear;
13 | animation: spin 2s infinite linear;
14 | }
15 |
16 | /* Prevent stack and spinners from being taken inline when inside a link */
17 | a .icon-stack,
18 | a .icon-spin {
19 | display: inline-block;
20 | text-decoration: none;
21 | }
22 |
23 | @-moz-keyframes spin {
24 | 0% { -moz-transform: rotate(0deg); }
25 | 100% { -moz-transform: rotate(359deg); }
26 | }
27 | @-webkit-keyframes spin {
28 | 0% { -webkit-transform: rotate(0deg); }
29 | 100% { -webkit-transform: rotate(359deg); }
30 | }
31 | @-o-keyframes spin {
32 | 0% { -o-transform: rotate(0deg); }
33 | 100% { -o-transform: rotate(359deg); }
34 | }
35 | @-ms-keyframes spin {
36 | 0% { -ms-transform: rotate(0deg); }
37 | 100% { -ms-transform: rotate(359deg); }
38 | }
39 | @keyframes spin {
40 | 0% { transform: rotate(0deg); }
41 | 100% { transform: rotate(359deg); }
42 | }
43 |
44 | /* Icon rotations and mirroring */
45 | .icon-rotate-90:before {
46 | -webkit-transform: rotate(90deg);
47 | -moz-transform: rotate(90deg);
48 | -ms-transform: rotate(90deg);
49 | -o-transform: rotate(90deg);
50 | transform: rotate(90deg);
51 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
52 | }
53 |
54 | .icon-rotate-180:before {
55 | -webkit-transform: rotate(180deg);
56 | -moz-transform: rotate(180deg);
57 | -ms-transform: rotate(180deg);
58 | -o-transform: rotate(180deg);
59 | transform: rotate(180deg);
60 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
61 | }
62 |
63 | .icon-rotate-270:before {
64 | -webkit-transform: rotate(270deg);
65 | -moz-transform: rotate(270deg);
66 | -ms-transform: rotate(270deg);
67 | -o-transform: rotate(270deg);
68 | transform: rotate(270deg);
69 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
70 | }
71 |
72 | .icon-flip-horizontal:before {
73 | -webkit-transform: scale(-1, 1);
74 | -moz-transform: scale(-1, 1);
75 | -ms-transform: scale(-1, 1);
76 | -o-transform: scale(-1, 1);
77 | transform: scale(-1, 1);
78 | }
79 |
80 | .icon-flip-vertical:before {
81 | -webkit-transform: scale(1, -1);
82 | -moz-transform: scale(1, -1);
83 | -ms-transform: scale(1, -1);
84 | -o-transform: scale(1, -1);
85 | transform: scale(1, -1);
86 | }
87 |
88 | /* ensure rotation occurs inside anchor tags */
89 | a {
90 | .icon-rotate-90, .icon-rotate-180, .icon-rotate-270, .icon-flip-horizontal, .icon-flip-vertical {
91 | &:before { display: inline-block; }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin icon($icon) {
5 | @include icon-FontAwesome();
6 | content: $icon;
7 | }
8 |
9 | @mixin icon-FontAwesome() {
10 | font-family: FontAwesome;
11 | font-weight: normal;
12 | font-style: normal;
13 | text-decoration: inherit;
14 | -webkit-font-smoothing: antialiased;
15 | *margin-right: .3em; // fixes ie7 issues
16 | }
17 |
18 | @mixin border-radius($radius) {
19 | -webkit-border-radius: $radius;
20 | -moz-border-radius: $radius;
21 | border-radius: $radius;
22 | }
23 |
24 | @mixin icon-stack($width: 2em, $height: 2em, $top-font-size: 1em, $base-font-size: 2em) {
25 | .icon-stack {
26 | position: relative;
27 | display: inline-block;
28 | width: $width;
29 | height: $height;
30 | line-height: $width;
31 | vertical-align: -35%;
32 | [class^="icon-"],
33 | [class*=" icon-"] {
34 | display: block;
35 | text-align: center;
36 | position: absolute;
37 | width: 100%;
38 | height: 100%;
39 | font-size: $top-font-size;
40 | line-height: inherit;
41 | *line-height: $height;
42 | }
43 | .icon-stack-base {
44 | font-size: $base-font-size;
45 | *line-height: #{$height / $base-font-size}em;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$FontAwesomePath}/fontawesome-webfont.eot?v=#{$FontAwesomeVersion}');
7 | src: url('#{$FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=#{$FontAwesomeVersion}') format('embedded-opentype'),
8 | url('#{$FontAwesomePath}/fontawesome-webfont.woff?v=#{$FontAwesomeVersion}') format('woff'),
9 | url('#{$FontAwesomePath}/fontawesome-webfont.ttf?v=#{$FontAwesomeVersion}') format('truetype'),
10 | url('#{$FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular?v=#{$FontAwesomeVersion}') format('svg');
11 | // src: url('#{$FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
12 | font-weight: normal;
13 | font-style: normal;
14 | }
15 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/automatic/static/css/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 3.2.1
3 | * the iconic font designed for Bootstrap
4 | * ------------------------------------------------------------------------------
5 | * The full suite of pictographic icons, examples, and documentation can be
6 | * found at http://fontawesome.io. Stay up to date on Twitter at
7 | * http://twitter.com/fontawesome.
8 | *
9 | * License
10 | * ------------------------------------------------------------------------------
11 | * - The Font Awesome font is licensed under SIL OFL 1.1 -
12 | * http://scripts.sil.org/OFL
13 | * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License -
14 | * http://opensource.org/licenses/mit-license.html
15 | * - Font Awesome documentation licensed under CC BY 3.0 -
16 | * http://creativecommons.org/licenses/by/3.0/
17 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
18 | * "Font Awesome by Dave Gandy - http://fontawesome.io"
19 | *
20 | * Author - Dave Gandy
21 | * ------------------------------------------------------------------------------
22 | * Email: dave@fontawesome.io
23 | * Twitter: http://twitter.com/byscuits
24 | * Work: Lead Product Designer @ Kyruus - http://kyruus.com
25 | */
26 |
27 | @import "variables";
28 | @import "mixins";
29 | @import "path";
30 | @import "core";
31 | @import "bootstrap";
32 | @import "extras";
33 | @import "icons";
34 |
--------------------------------------------------------------------------------
/automatic/static/css/wheelmenu.css:
--------------------------------------------------------------------------------
1 | /* Required Stylesheets */
2 |
3 | a {
4 | text-decoration: none;
5 | }
6 |
7 | .wheel-button {
8 | position: relative;
9 | }
10 |
11 | .wheel {
12 | margin: 0;
13 | padding: 0;
14 | list-style: none;
15 | width: 260px; /* this will determine the diameter of the circle */
16 | height: 200px; /* this will determine the diameter of the circle */
17 | visibility: hidden;
18 | position: relative;
19 | display: none;
20 | }
21 |
22 | .wheel li {
23 | overflow: hidden;
24 | float: left;
25 | }
26 |
27 | .wheel li a {
28 | display: block;
29 | }
30 |
31 | .wheel-button, .wheel-button:visited {
32 | line-height: 35px;
33 | font-weight: bold;
34 | font-size: 36px;
35 | background: #df4727;
36 | padding: 10px 11px;
37 | text-align: center;
38 | border-radius: 50px;
39 | width: 60px;
40 | height: 60px;
41 | color: white;
42 | display: block;
43 | margin: 70px auto 20px;
44 | border: 3px solid #92311e;
45 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
46 | -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
47 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
48 | }
49 |
50 | .wheel-button:hover {
51 | color: white;
52 | }
53 |
54 | .wheel-button.ne {
55 | border-color: white;
56 | background: #35b0ee;
57 | color: #0277bd;
58 | position: absolute;
59 | bottom: 50px;
60 | left: 0px;
61 | }
62 |
63 | .wheel-button.nw {
64 | border-color: white;
65 | background-color: #E67E22;
66 | color: #FFFC44;
67 | position: absolute;
68 | bottom: 10px;
69 | right: 10px;
70 | }
71 |
72 | .wheel-button span, .wheel span {
73 | position: relative;
74 | -moz-transition: all 1s ease;
75 | -webkit-transition: all 1s ease;
76 | -o-transition: all 1s ease;
77 | transition: all 1s ease;
78 | display: block;
79 | }
80 |
81 | .wheel-button.active span {
82 | transform: rotate(135deg);
83 | -ms-transform: rotate(135deg); /* IE 9 */
84 | -webkit-transform: rotate(135deg); /* Safari and Chrome */
85 | }
86 |
87 | .wheel-button.ne span{
88 | font-size:28px;
89 | line-height:32px;
90 | font-family: sans-serif;
91 | }
92 | .wheel li a, .wheel li a:visited {
93 | background: rgba(0, 0, 0, 0.65);
94 | border-radius: 50px;
95 | font-weight: bold;
96 | padding: 10px;
97 | text-align: center;
98 | width: 40px;
99 | height: 40px;
100 | border: 1px solid black;
101 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 1px rgba(255, 255, 255, 0.5);
102 | -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 1px rgba(255, 255, 255, 0.5);
103 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 1px rgba(255, 255, 255, 0.5);
104 | color: white;
105 | -moz-transition: all 0.25s ease;
106 | -webkit-transition: all 0.25s ease;
107 | -o-transition: all 0.25s ease;
108 | transition: all 0.25s ease;
109 | }
110 |
111 | .wheel li a:hover {
112 | background: rgba(0, 0, 0, 0.8);
113 | }
--------------------------------------------------------------------------------
/automatic/static/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/automatic/static/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/automatic/static/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/automatic/static/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/automatic/static/fonts/meteocons/meteocons-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/meteocons/meteocons-webfont.eot
--------------------------------------------------------------------------------
/automatic/static/fonts/meteocons/meteocons-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/meteocons/meteocons-webfont.ttf
--------------------------------------------------------------------------------
/automatic/static/fonts/meteocons/meteocons-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/fonts/meteocons/meteocons-webfont.woff
--------------------------------------------------------------------------------
/automatic/static/image/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/background.jpg
--------------------------------------------------------------------------------
/automatic/static/image/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/background1.jpg
--------------------------------------------------------------------------------
/automatic/static/image/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/background2.jpg
--------------------------------------------------------------------------------
/automatic/static/image/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/favicon.ico
--------------------------------------------------------------------------------
/automatic/static/image/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/logo.png
--------------------------------------------------------------------------------
/automatic/static/image/wx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/image/wx.jpg
--------------------------------------------------------------------------------
/automatic/static/images/ak-common.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-common.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon01.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon02.jpg
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon03.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon04.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon05.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-person-icon06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-person-icon06.png
--------------------------------------------------------------------------------
/automatic/static/images/ak-z-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/ak-z-icon.png
--------------------------------------------------------------------------------
/automatic/static/images/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/app.png
--------------------------------------------------------------------------------
/automatic/static/images/app_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/app_current.png
--------------------------------------------------------------------------------
/automatic/static/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/background.jpg
--------------------------------------------------------------------------------
/automatic/static/images/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/background1.jpg
--------------------------------------------------------------------------------
/automatic/static/images/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/background2.jpg
--------------------------------------------------------------------------------
/automatic/static/images/channel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/channel.png
--------------------------------------------------------------------------------
/automatic/static/images/channel_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/channel_current.png
--------------------------------------------------------------------------------
/automatic/static/images/chat01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/chat01.png
--------------------------------------------------------------------------------
/automatic/static/images/cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/cloud.png
--------------------------------------------------------------------------------
/automatic/static/images/cloud_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/cloud_current.png
--------------------------------------------------------------------------------
/automatic/static/images/custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/custom.png
--------------------------------------------------------------------------------
/automatic/static/images/custom_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/custom_current.png
--------------------------------------------------------------------------------
/automatic/static/images/dotted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/dotted.png
--------------------------------------------------------------------------------
/automatic/static/images/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/download.png
--------------------------------------------------------------------------------
/automatic/static/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/favicon.ico
--------------------------------------------------------------------------------
/automatic/static/images/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/home.png
--------------------------------------------------------------------------------
/automatic/static/images/home_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/home_current.png
--------------------------------------------------------------------------------
/automatic/static/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/icon.png
--------------------------------------------------------------------------------
/automatic/static/images/line_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/line_bg.png
--------------------------------------------------------------------------------
/automatic/static/images/logo-automagic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/logo-automagic.png
--------------------------------------------------------------------------------
/automatic/static/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/logo.png
--------------------------------------------------------------------------------
/automatic/static/images/select_xl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/select_xl.png
--------------------------------------------------------------------------------
/automatic/static/images/select_xl01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/select_xl01.png
--------------------------------------------------------------------------------
/automatic/static/images/setting-top02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/setting-top02.png
--------------------------------------------------------------------------------
/automatic/static/images/sort_asc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/sort_asc.png
--------------------------------------------------------------------------------
/automatic/static/images/sort_both.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/sort_both.png
--------------------------------------------------------------------------------
/automatic/static/images/sort_desc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/sort_desc.png
--------------------------------------------------------------------------------
/automatic/static/images/source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/source.png
--------------------------------------------------------------------------------
/automatic/static/images/source_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/source_current.png
--------------------------------------------------------------------------------
/automatic/static/images/statistics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/statistics.png
--------------------------------------------------------------------------------
/automatic/static/images/statistics_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/statistics_current.png
--------------------------------------------------------------------------------
/automatic/static/images/syetem_management.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/syetem_management.png
--------------------------------------------------------------------------------
/automatic/static/images/syetem_management_c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/syetem_management_c.png
--------------------------------------------------------------------------------
/automatic/static/images/system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/system.png
--------------------------------------------------------------------------------
/automatic/static/images/system_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/system_current.png
--------------------------------------------------------------------------------
/automatic/static/images/timg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/timg.png
--------------------------------------------------------------------------------
/automatic/static/images/user-13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/user-13.jpg
--------------------------------------------------------------------------------
/automatic/static/images/xiaoxi01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/xiaoxi01.png
--------------------------------------------------------------------------------
/automatic/static/images/xiaoxi01g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/xiaoxi01g.png
--------------------------------------------------------------------------------
/automatic/static/images/zkonw-back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/images/zkonw-back.png
--------------------------------------------------------------------------------
/automatic/static/js/back-to-top.js:
--------------------------------------------------------------------------------
1 | //** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.
2 | //** Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09')
3 | //** v1.1 (April 7th, 09'):
4 | //** 1) Adds ability to scroll to an absolute position (from top of page) or specific element on the page instead.
5 | //** 2) Fixes scroll animation not working in Opera.
6 |
7 |
8 | var scrolltotop={
9 | //startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control
10 | //scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top).
11 | setting: {startline:100, scrollto: 0, scrollduration:1000, fadeduration:[500, 100]},
12 | controlHTML: '', //
//HTML for control, which is auto wrapped in DIV w/ ID="topcontrol"
13 | controlattrs: {offsetx:5, offsety:5}, //offset of control relative to right/ bottom of window corner
14 | anchorkeyword: '#top', //Enter href value of HTML anchors on the page that should also act as "Scroll Up" links
15 |
16 | state: {isvisible:false, shouldvisible:false},
17 |
18 | scrollup:function(){
19 | if (!this.cssfixedsupport) //if control is positioned using JavaScript
20 | this.$control.css({opacity:0}) //hide control immediately after clicking it
21 | var dest=isNaN(this.setting.scrollto)? this.setting.scrollto : parseInt(this.setting.scrollto)
22 | if (typeof dest=="string" && jQuery('#'+dest).length==1) //check element set by string exists
23 | dest=jQuery('#'+dest).offset().top
24 | else
25 | dest=0
26 | this.$body.animate({scrollTop: dest}, this.setting.scrollduration);
27 | },
28 |
29 | keepfixed:function(){
30 | var $window=jQuery(window)
31 | var controlx=$window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx
32 | var controly=$window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety
33 | this.$control.css({left:controlx+'px', top:controly+'px'})
34 | },
35 |
36 | togglecontrol:function(){
37 | var scrolltop=jQuery(window).scrollTop()
38 | if (!this.cssfixedsupport)
39 | this.keepfixed()
40 | this.state.shouldvisible=(scrolltop>=this.setting.startline)? true : false
41 | if (this.state.shouldvisible && !this.state.isvisible){
42 | this.$control.stop().animate({opacity:1}, this.setting.fadeduration[0])
43 | this.state.isvisible=true
44 | }
45 | else if (this.state.shouldvisible==false && this.state.isvisible){
46 | this.$control.stop().animate({opacity:0}, this.setting.fadeduration[1])
47 | this.state.isvisible=false
48 | }
49 | },
50 |
51 | init:function(){
52 | jQuery(document).ready(function($){
53 | var mainobj=scrolltotop
54 | var iebrws=document.all
55 | mainobj.cssfixedsupport=!iebrws || iebrws && document.compatMode=="CSS1Compat" && window.XMLHttpRequest //not IE or IE7+ browsers in standards mode
56 | mainobj.$body=(window.opera)? (document.compatMode=="CSS1Compat"? $('html') : $('body')) : $('html,body')
57 | mainobj.$control=$(''+mainobj.controlHTML+'
')
58 | .css({position:mainobj.cssfixedsupport? 'fixed' : 'absolute', bottom:mainobj.controlattrs.offsety, right:mainobj.controlattrs.offsetx, opacity:0, cursor:'pointer'})
59 | .attr({title:'Scroll Back to Top'})
60 | .click(function(){mainobj.scrollup(); return false})
61 | .appendTo('body')
62 | if (document.all && !window.XMLHttpRequest && mainobj.$control.text()!='') //loose check for IE6 and below, plus whether control contains any text
63 | mainobj.$control.css({width:mainobj.$control.width()}) //IE6- seems to require an explicit width on a DIV containing text
64 | mainobj.togglecontrol()
65 | $('a[href="' + mainobj.anchorkeyword +'"]').click(function(){
66 | mainobj.scrollup()
67 | return false
68 | })
69 | $(window).bind('scroll resize', function(e){
70 | mainobj.togglecontrol()
71 | })
72 | })
73 | }
74 | }
75 |
76 | scrolltotop.init()
--------------------------------------------------------------------------------
/automatic/static/js/common.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * RENAISSANCE - Responsive Admin Theme
4 | * version 1.3.0
5 | *
6 | */
7 |
8 | var datetime = null,
9 | date = null;
10 |
11 | var update = function () {
12 | date = moment(new Date())
13 | datetime.html(date.format('h:mm A'));
14 | };
15 |
16 | $(window).on('load', function(){
17 | //Preloader
18 | setTimeout(function(){
19 | $('.preloader').fadeOut(100);
20 | }, 500);
21 | });
22 |
23 |
24 | // check if browser support HTML5 local storage
25 | function localStorageSupport() {
26 | return (('localStorage' in window) && window['localStorage'] !== null)
27 | }
28 |
29 |
30 | //Personal working platform Sidebar
31 |
32 | $("li.perwork-btn").click(function(){
33 |
34 | $(this).toggleClass("active").siblings().removeClass("active");
35 |
36 | var currentEle=$(this);
37 |
38 | var siblingsElel=currentEle.siblings("li.members-btn");
39 |
40 | $.each(siblingsElel,function(index,ele){
41 | $("#"+$(ele).data("href")).removeClass('members-sidebar-open');
42 | if($("#"+$(ele).data("href")).hasClass('dropdown-menu')){
43 | $("#"+$(ele).data("href")).attr("aria-expanded","false");
44 | $(ele).removeClass("open").removeClass("active");
45 | }
46 | });
47 |
48 | cta($(this)[0], $("#"+currentEle.data("href"))[0], {relativeToWindow: true}, function () {
49 | if($("#"+currentEle.data("href")).hasClass('dropdown-menu')){
50 | $("#"+currentEle.data("href")).attr("aria-expanded","true");
51 | currentEle.toggleClass("open");
52 | }else{
53 | $("#"+currentEle.data("href")).toggleClass('members-sidebar-open');
54 | }
55 | });
56 |
57 | $(currentEle.data("close")).click(function(){
58 | $("#"+currentEle.data("href")).removeClass('members-sidebar-open');
59 | currentEle.removeClass('active');
60 | });
61 | return false;
62 |
63 | });
64 |
65 |
--------------------------------------------------------------------------------
/automatic/static/js/keyword.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Ray on 16-11-11.
3 | */
4 |
5 | /* 点击关键字编辑按钮 */
6 | function setkeywordValue(id){
7 |
8 | $.ajax({
9 | type:"GET",
10 | data:{'keywordid':id},
11 | url: "/func/keyword/setedit/",
12 | cache: false,
13 | dataType:'json',
14 |
15 | success: function(result,TextStatus) {
16 | if (result.length >0){
17 | for(var i=0; i');
28 | var $selvalue = $('');
29 | $ipt.width(options.width - 8);//设定文本框宽度
30 | var $this = $(this);
31 | $this.width(options.width);
32 | $ipt.appendTo($this);
33 | $selvalue.appendTo($this);
34 |
35 | //创建 下拉选项
36 |
37 | //1.下拉选项包裹
38 | var $container = $('');
39 |
40 | //2.创建 全选和确认按钮 top层
41 | var $top = $('');//外层div包裹
42 | var $all = $('');//全选
43 | var $btn = $('');
44 | $all.appendTo($top);
45 | $btn.appendTo($top);
46 |
47 | //3.下拉中的内容 content层
48 | var $content = $('');//外层div包裹
49 | var count = options.data.length;
50 | var h = ( (count * 22) > parseInt(options.maxheight) ) ? options.maxheight : "'" + count * 22 + "'";
51 | $content.height(h);
52 | for(var i = count-1; i >= 0; i--){
53 |
54 | var $list = $('
');
55 | $list.appendTo($content);
56 | }
57 |
58 | //4把top层和content层加到$container下
59 | $top.appendTo($container);
60 | $content.appendTo($container);
61 |
62 | //把$container加到$(this)下
63 | $container.appendTo($this);
64 |
65 |
66 | //js Effect
67 | var $dropList = $content.children().children('input');
68 |
69 | $all.change(function (){//点击all
70 |
71 | var opt_arr = [];
72 | var opt_arry = [];
73 | $dropList.each(function (){
74 | if($all.is(':checked')){
75 | $(this)[0].checked = 'checked';
76 | opt_arr.push($(this).val());
77 | opt_arry.push($(this).next().text());
78 | }else{
79 | $(this)[0].checked = '';
80 | opt_arr=[];
81 | opt_arry= [];
82 | }
83 | });
84 |
85 | $ipt.val(opt_arry.join(';'));
86 | $selvalue.val(opt_arr.join(';'));
87 | });
88 |
89 | $container.addClass('hidden');//开始隐藏
90 |
91 | $ipt.focus(function (){//文本框处于编辑
92 | $container.removeClass('hidden');
93 | $this.addClass('multi_select_focus');
94 | });
95 |
96 | $btn.click(function (){//点击 ok按钮
97 | $container.addClass('hidden');
98 | $this.removeClass('multi_select_focus');
99 | });
100 |
101 |
102 | $dropList.change(function (){//勾选选项
103 | var opt_arr = [];
104 | var opt_arry = [];
105 | $dropList.each(function (){
106 | if ($(this).is(':checked')){
107 | opt_arr.push($(this).val());
108 | opt_arry.push($(this).next().text());
109 | }
110 |
111 | });
112 | var $dropList_selected = $content.children().children('input:checked');
113 | $selvalue.val(opt_arr.join(';'));
114 | $ipt.val(opt_arry.join(';'));
115 | var o = $all[0];
116 | var n1 = $dropList_selected.length;
117 | var n2 = $dropList.length;
118 | o.checked = (n1 === n2) ? 'checked' : '';
119 | });
120 | });
121 | },
122 | });
123 | })(jQuery);
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/awesomeStyle/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/awesomeStyle/img/loading.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/demo.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {
2 | margin: 0;padding: 0;border: 0;outline: 0;font-weight: inherit;font-style: inherit;font-size: 100%;font-family: inherit;vertical-align: baseline;}
3 | body {color: #2f332a;font: 15px/21px Arial, Helvetica, simsun, sans-serif;background: #f0f6e4 \9;}
4 | h1, h2, h3, h4, h5, h6 {color: #2f332a;font-weight: bold;font-family: Helvetica, Arial, sans-serif;padding-bottom: 5px;}
5 | h1 {font-size: 24px;line-height: 34px;text-align: center;}
6 | h2 {font-size: 14px;line-height: 24px;padding-top: 5px;}
7 | h6 {font-weight: normal;font-size: 12px;letter-spacing: 1px;line-height: 24px;text-align: center;}
8 | a {color:#3C6E31;text-decoration: underline;}
9 | a:hover {background-color:#3C6E31;color:white;}
10 | input.radio {margin: 0 2px 0 8px;}
11 | input.radio.first {margin-left:0;}
12 | input.empty {color: lightgray;}
13 | code {color: #2f332a;}
14 | .highlight_red {color:#A60000;}
15 | .highlight_green {color:#A7F43D;}
16 | li {list-style: circle;font-size: 12px;}
17 | li.title {list-style: none;}
18 | ul.list {margin-left: 17px;}
19 |
20 | div.content_wrap {width: 600px;height:380px;}
21 | div.content_wrap div.left{float: left;width: 250px;}
22 | div.content_wrap div.right{float: right;width: 340px;}
23 | div.zTreeDemoBackground {width:250px;height:362px;text-align:left;}
24 |
25 | ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #f0f6e4;width:220px;height:360px;overflow-y:scroll;overflow-x:auto;}
26 | ul.log {border: 1px solid #617775;background: #f0f6e4;width:300px;height:170px;overflow: hidden;}
27 | ul.log.small {height:45px;}
28 | ul.log li {color: #666666;list-style: none;padding-left: 10px;}
29 | ul.log li.dark {background-color: #E3E3E3;}
30 |
31 | /* ruler */
32 | div.ruler {height:20px; width:220px; background-color:#f0f6e4;border: 1px solid #333; margin-bottom: 5px; cursor: pointer}
33 | div.ruler div.cursor {height:20px; width:30px; background-color:#3C6E31; color:white; text-align: right; padding-right: 5px; cursor: pointer}
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/metroStyle/img/line_conn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/metroStyle/img/line_conn.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/metroStyle/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/metroStyle/img/loading.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/metroStyle/img/metro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/metroStyle/img/metro.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/metroStyle/img/metro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/metroStyle/img/metro.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/1_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/1_close.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/1_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/1_open.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/2.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/3.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/4.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/5.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/6.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/7.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/8.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/diy/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/diy/9.png
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/line_conn.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/line_conn.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/loading.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/zTreeStandard.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/zTreeStandard.gif
--------------------------------------------------------------------------------
/automatic/static/zTree_v3/css/zTreeStyle/img/zTreeStandard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/radiateboy/automagic/2c0f40bf9dadca49b950ec02f2c9257a9e8f4786/automatic/static/zTree_v3/css/zTreeStyle/img/zTreeStandard.png
--------------------------------------------------------------------------------
/automatic/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends 'frame.html' %}
2 | {% block title %}Automagic{% endblock %}
3 | {% block slideshow %}
4 |
5 |

6 |
7 | {% endblock %}
--------------------------------------------------------------------------------
/automatic/templates/500.html:
--------------------------------------------------------------------------------
1 | {% extends 'frame.html' %}
2 | {% block title %}Automagic{% endblock %}
3 | {% block slideshow %}
4 |
5 |

6 |
7 | {% endblock %}
--------------------------------------------------------------------------------
/automatic/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {% block title %}Default Title{% endblock %} - Ray
6 |
7 |
8 | {% include 'nav.html' %}
9 |
10 | {% block content %}
11 | 这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。
12 | {% for key,value in info_dict.items %}
13 | {{ key }}:{{ value }}
14 | {% endfor %}
15 |
16 | (zhandian):{{ info_dict.site }}
17 | (neirong):{{ info_dict.content }}
18 | {% endblock %}
19 | add product
20 |
21 |
22 |
--------------------------------------------------------------------------------
/automatic/templates/comingsoon.html:
--------------------------------------------------------------------------------
1 | {% extends 'frame.html' %}
2 | {% block title %}Automagic{% endblock %}
3 | {% block slideshow %}
4 |
5 |

6 |
7 | {% endblock %}
--------------------------------------------------------------------------------
/automatic/templates/management/moduleadd.html:
--------------------------------------------------------------------------------
1 | {% extends 'nav.html' %}
2 | {% block title %}Module Add{% endblock %}
3 |
4 | {% block slideshow %}
5 |
6 |
14 |
7 | {% if errors %}
8 |
9 | {% for error in errors %}
10 | - {{error}}
11 | {% endfor %}
12 |
13 | {% endif %}
14 |
15 |
16 | {{module.name}}
17 |
18 |
19 | ISENABLED: |
20 | {{ module.isenabled }} |
21 |
22 |
23 | {{ module.createat }}: |
24 | {{ module.createtime }} |
25 |
26 |
27 | {{ module.updateat }}: |
28 | {{ module.updatetime }} |
29 |
30 |
31 |
32 |
33 |
34 |
35 | NO. |
36 | Module Name |
37 | IsEnabled |
38 | Create At |
39 | Create Time |
40 | Update At |
41 | Update Time |
42 | |
43 |
44 |
45 |
46 | {% for module in modulelist %}
47 |
48 | {{ forloop.counter }} |
49 | {{ module.name }} |
50 | {{ module.isenabled }} |
51 | {{ module.createat }} |
52 | {{ module.createtime }} |
53 | {{ module.createat }} |
54 | {{ module.updatetime }} |
55 |
56 | Edit
57 | Delete
58 | |
59 |
60 | {% endfor %}
61 |
62 |
63 |
64 |