merge cmdb

pull/530/head
wangyong 2016-09-06 18:45:40 +08:00
commit bc232c4f77
42 changed files with 1073 additions and 1048 deletions

View File

@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _
class AssetForm(forms.ModelForm): class AssetForm(forms.ModelForm):
class Meta: class Meta:
model = Asset model = Asset
@ -22,6 +21,25 @@ class AssetForm(forms.ModelForm):
class AssetGroupForm(forms.ModelForm): class AssetGroupForm(forms.ModelForm):
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
label=_('Asset'),
required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
)
def __init__(self, *args, **kwargs):
if kwargs.get('instance'):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super(AssetGroupForm, self).__init__(*args, **kwargs)
def _save_m2m(self):
super(AssetGroupForm, self)._save_m2m()
assets = self.cleaned_data['assets']
self.instance.assets.clear()
self.instance.assets.add(*tuple(assets))
class Meta: class Meta:
model = AssetGroup model = AssetGroup
fields = [ fields = [

View File

@ -0,0 +1,181 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-09-04 11:52
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='AdminUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
('username', models.CharField(max_length=16, verbose_name='Username')),
('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
('private_key', models.CharField(blank=True, max_length=4096, null=True, verbose_name='SSH private key')),
('is_default', models.BooleanField(default=False, verbose_name='As default')),
('auto_update', models.BooleanField(default=True, verbose_name='Auto update pass/key')),
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
('create_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
],
options={
'db_table': 'adminuser',
},
),
migrations.CreateModel(
name='Asset',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ip', models.CharField(max_length=32, verbose_name='IP')),
('other_ip', models.CharField(blank=True, max_length=255, verbose_name='Other IP')),
('remote_card_ip', models.CharField(blank=True, max_length=16, verbose_name='Remote card IP')),
('hostname', models.CharField(blank=True, max_length=128, unique=True, verbose_name='Hostname')),
('port', models.IntegerField(default=22, verbose_name='Port')),
('username', models.CharField(blank=True, max_length=16, verbose_name='Admin user')),
('password', models.CharField(blank=True, max_length=256, verbose_name='Admin password')),
('mac_addr', models.CharField(blank=True, max_length=20, verbose_name='Mac address')),
('brand', models.CharField(blank=True, max_length=64, verbose_name='Brand')),
('cpu', models.CharField(blank=True, max_length=64, verbose_name='CPU')),
('memory', models.CharField(blank=True, max_length=128, verbose_name='Memory')),
('disk', models.CharField(blank=True, max_length=1024, verbose_name='Disk')),
('os', models.CharField(blank=True, max_length=128, verbose_name='OS')),
('cabinet_no', models.CharField(blank=True, max_length=32, verbose_name='Cabinet number')),
('cabinet_pos', models.IntegerField(blank=True, verbose_name='Cabinet position')),
('number', models.CharField(blank=True, max_length=32, unique=True, verbose_name='Asset number')),
('sn', models.CharField(blank=True, max_length=128, unique=True, verbose_name='Serial number')),
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
('admin_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.AdminUser', verbose_name='Admin User')),
],
options={
'db_table': 'asset',
},
),
migrations.CreateModel(
name='AssetExtend',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.CharField(max_length=64, verbose_name='KEY')),
('value', models.CharField(max_length=64, verbose_name='VALUE')),
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
],
options={
'db_table': 'assetextend',
},
),
migrations.CreateModel(
name='AssetGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=64, unique=True, verbose_name='Name')),
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
],
options={
'db_table': 'assetgroup',
},
),
migrations.CreateModel(
name='IDC',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, verbose_name='Name')),
('bandwidth', models.CharField(blank=True, max_length=32, verbose_name='Bandwidth')),
('contact', models.CharField(blank=True, max_length=16, verbose_name='Contact')),
('phone', models.CharField(blank=True, max_length=32, verbose_name='Phone')),
('address', models.CharField(blank=True, max_length=128, verbose_name='Address')),
('network', models.TextField(blank=True, verbose_name='Network')),
('date_added', models.DateField(auto_now=True, null=True, verbose_name='Date added')),
('operator', models.CharField(blank=True, max_length=32, verbose_name='Operator')),
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
],
options={
'db_table': 'idc',
},
),
migrations.CreateModel(
name='Label',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.CharField(max_length=64, verbose_name='KEY')),
('value', models.CharField(max_length=64, verbose_name='VALUE')),
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
('asset', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.Asset', verbose_name='Asset')),
],
options={
'db_table': 'label',
},
),
migrations.CreateModel(
name='SysUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128, verbose_name='Name')),
('username', models.CharField(max_length=16, verbose_name='Username')),
('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
('protocol', models.CharField(default='ssh', max_length=16, verbose_name='Protocol')),
('private_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH private key')),
('public_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH public key')),
('is_default', models.BooleanField(default=False, verbose_name='As default')),
('auto_push', models.BooleanField(default=True, verbose_name='Auto push')),
('auto_update', models.BooleanField(default=True, verbose_name='Auto update pass/key')),
('sudo', models.TextField(blank=True, max_length=4096, verbose_name='Sudo')),
('shell', models.CharField(blank=True, max_length=64, verbose_name='Shell')),
('home', models.CharField(blank=True, max_length=64, verbose_name='Home')),
('uid', models.IntegerField(blank=True, verbose_name='Uid')),
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
('create_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
],
options={
'db_table': 'sysuser',
},
),
migrations.AddField(
model_name='asset',
name='env',
field=models.ManyToManyField(related_name='asset_env_extend', to='assets.AssetExtend', verbose_name='Asset environment'),
),
migrations.AddField(
model_name='asset',
name='groups',
field=models.ManyToManyField(to='assets.AssetGroup', verbose_name='Asset groups'),
),
migrations.AddField(
model_name='asset',
name='idc',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.IDC', verbose_name='IDC'),
),
migrations.AddField(
model_name='asset',
name='status',
field=models.ManyToManyField(related_name='asset_status_extend', to='assets.AssetExtend', verbose_name='Asset status'),
),
migrations.AddField(
model_name='asset',
name='sys_user',
field=models.ManyToManyField(to='assets.SysUser', verbose_name='Sys User'),
),
migrations.AddField(
model_name='asset',
name='type',
field=models.ManyToManyField(related_name='asset_type_extend', to='assets.AssetExtend', verbose_name='Asset type'),
),
]

View File

@ -14,7 +14,7 @@ class AssetGroup(models.Model):
return self.name return self.name
class Meta: class Meta:
db_table = 'assetgroup' db_table = 'asset_group'
class IDC(models.Model): class IDC(models.Model):
@ -128,10 +128,14 @@ class Asset(models.Model):
comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment')) comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.ip return '%(ip)s:%(port)d' % {'ip': self.ip, 'port': self.port}
def initial(self):
pass
class Meta: class Meta:
db_table = 'asset' db_table = 'asset'
index_together = ('ip', 'port')
class Label(models.Model): class Label(models.Model):

View File

@ -40,24 +40,9 @@
{{ form.port|bootstrap_horizontal }} {{ form.port|bootstrap_horizontal }}
{# <div class="form-group" id="id_port">#}
{# <label class="col-sm-2 control-label">端口</label>#}
{# <div class="col-sm-9">#}
{# <input type="text" placeholder="" name="port" class="form-control">#}
{# </div>#}
{# </div>#}
{# <div class="form-group" id="id_type">#}
{# <label class="col-sm-2 control-label">资产类型</label>#}
{# <div class="col-sm-9">#}
{# <input type="text" placeholder="" name="type" class="form-control">#}
{# </div>#}
{# </div>#}
{{ form.type|bootstrap_horizontal }} {{ form.type|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>关联资产用户</h3> <h3>关联资产用户</h3>
<div class="form-group"> <div class="form-group">

View File

@ -30,24 +30,25 @@
<form method="post" id="userForm" class="form-horizontal" action="" > <form method="post" id="userForm" class="form-horizontal" action="" >
{% csrf_token %} {% csrf_token %}
{{ form.name|bootstrap_horizontal }} {{ form.name|bootstrap_horizontal }}
{{ form.assets|bootstrap_horizontal }}
<div class="form-group"> {# <div class="form-group">#}
<label for="users" class="col-sm-2 control-label">{% trans 'Asset' %}</label> {# <label for="users" class="col-sm-2 control-label">{% trans 'Asset' %}</label>#}
<div class="col-sm-9"> {# <div class="col-sm-9">#}
<select name="assets" id="assets" data-placeholder="{% trans 'Select asset' %}" class="select2 form-control m-b" multiple tabindex="2"> {# <select name="assets" id="assets" data-placeholder="{% trans 'Select asset' %}" class="select2 form-control m-b" multiple tabindex="2">#}
{% for asset in assets %} {# {% for asset in assets %}#}
<option value="{{ asset.id }}">{{ asset.hostname }}</option> {# <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>#}
{% endfor %} {# {% endfor %}#}
</select> {# </select>#}
</div> {# </div>#}
</div> {# </div>#}
{{ form.comment|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }}
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button> <button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div> </div>
</div> </div>
</form> </form>

View File

@ -2,35 +2,35 @@
{% load i18n %} {% load i18n %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block content_left_head %}
<a href="{% url 'assets:assetgroup-add' %}" class="btn btn-sm btn-primary "> {% trans "Create asset group" %} </a> <a href="{% url 'assets:asset-group-create' %}" class="btn btn-sm btn-primary "> {% trans "Create asset group" %} </a>
{% endblock %} {% endblock %}
{% block table_head %} {% block table_head %}
<th class="text-center"> <th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')"> <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th> </th>
<th class="text-center"><a href="{% url 'assets:assetgroup-list' %}?sort=name">{% trans 'Name' %}</a></th> <th class="text-center"><a href="{% url 'assets:asset-group-list' %}?sort=name">{% trans 'Name' %}</a></th>
<th class="text-center">{% trans 'Asset num' %}</th> <th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center"><a href="{% url 'assets:assetgroup-list' %}?sort=date_expired">{% trans 'Comment' %}</a></th> <th class="text-center"><a href="{% url 'assets:asset-group-list' %}?sort=date_expired">{% trans 'Comment' %}</a></th>
<th class="text-center"></th> <th class="text-center"></th>
{% endblock %} {% endblock %}
{% block table_body %} {% block table_body %}
{% for assetgroup in assetgroups %} {% for asset_group in asset_group_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"> <td class="text-center">
<input type="checkbox" name="checked" value="{{ user.id }}"> <input type="checkbox" name="checked" value="{{ asset_group.id }}">
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'assets:assetgroup-detail' pk=user.id %}"> <a href="{% url 'assets:asset-group-detail' pk=asset_group.id %}">
{{ assetgroup.name }} {{ asset_group.name }}
</a> </a>
</td> </td>
<td class="text-center">{{ assetgroup.comment }}</td> <td class="text-center">{{ asset_group.assets.count }}</td>
<td class="text-center">{{ assetgroup.comment }}</td> <td class="text-center">{{ asset_group.comment }}</td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a> <a href="{% url 'assets:asset-group-update' pk=asset_group.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a>
<a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">{% trans 'Delete' %}</a> <a href="{% url 'assets:asset-group-delete' pk=asset_group.id %}" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -48,12 +48,10 @@
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary"> <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Commit' %} {% trans 'Submit' %}
</button> </button>
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %}
{% block content %} {% block content %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
@ -23,7 +24,7 @@
<div class="ibox-content"> <div class="ibox-content">
<form id="asset_form"> <form id="asset_form">
<div class="col-sm-1" style="padding-left: 0"> <div class="col-sm-1" style="padding-left: 0">
<a href="{% url 'assets:asset-add' %}" class="btn btn-sm btn-primary "> 添加资产 </a> <a href="{% url 'assets:asset-create' %}" class="btn btn-sm btn-primary "> {% trans 'Create asset' %}</a>
</div> </div>
<div class="col-sm-7" style="padding-left: 0px"> <div class="col-sm-7" style="padding-left: 0px">

View File

@ -14,14 +14,14 @@ app_name = 'assets'
urlpatterns = [ urlpatterns = [
url(r'^$', views.AssetListView.as_view(), name='asset-index'), url(r'^$', views.AssetListView.as_view(), name='asset-index'),
url(r'^asset$', views.AssetListView.as_view(), name='asset-list'), url(r'^asset$', views.AssetListView.as_view(), name='asset-list'),
url(r'^asset/add$', views.AssetAddView.as_view(), name='asset-add'), url(r'^asset/create$', views.AssetCreateView.as_view(), name='asset-create'),
url(r'^asset/(?P<pk>[0-9]+)$', views.AssetDetailView.as_view(), name='asset-detail'), url(r'^asset/(?P<pk>[0-9]+)$', views.AssetDetailView.as_view(), name='asset-detail'),
url(r'^asset/(?P<pk>[0-9]+)$/edit', views.AssetEditView.as_view(), name='asset-edit'), url(r'^asset/(?P<pk>[0-9]+)$/update', views.AssetUpdateView.as_view(), name='asset-update'),
url(r'^asset/(?P<pk>[0-9]+)/delete$', views.AssetDeleteView.as_view(), name='asset-delete'), url(r'^asset/(?P<pk>[0-9]+)/delete$', views.AssetDeleteView.as_view(), name='asset-delete'),
url(r'^assetgroup$', views.AssetGroupListView.as_view(), name='assetgroup-list'), url(r'^asset-group$', views.AssetGroupListView.as_view(), name='asset-group-list'),
url(r'^assetgroup/add$', views.AssetGroupAddView.as_view(), name='assetgroup-add'), url(r'^asset-group/create$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
url(r'^assetgroup/(?P<pk>[0-9]+)$', views.AssetGroupDetailView.as_view(), name='assetgroup-detail'), url(r'^asset-group/(?P<pk>[0-9]+)$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'),
url(r'^assetgroup/(?P<pk>[0-9]+)$/edit', views.AssetGroupEditView.as_view(), name='assetgroup-edit'), url(r'^asset-group/(?P<pk>[0-9]+)/update$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
url(r'^assetgroup/(?P<pk>[0-9]+)/delete$', views.AssetGroupDeleteView.as_view(), name='assetgroup-delete'), url(r'^asset-group/(?P<pk>[0-9]+)/delete$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
# url(r'^api/v1.0/', include(router.urls)), # url(r'^api/v1.0/', include(router.urls)),
] ]

View File

@ -2,32 +2,32 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView, ListView from django.views.generic import TemplateView, ListView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.views.generic import TemplateView, ListView from django.views.generic import TemplateView, ListView
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from .models import Asset, AssetGroup, IDC, AssetExtend from .models import Asset, AssetGroup, IDC, AssetExtend
from .forms import AssetForm, AssetGroupForm from .forms import AssetForm, AssetGroupForm
from .utils import AdminUserRequiredMixin from .utils import AdminUserRequiredMixin
class AssetAddView(CreateView): class AssetCreateView(CreateView):
model = Asset model = Asset
form_class = AssetForm form_class = AssetForm
template_name = 'assets/asset_add.html' template_name = 'assets/asset_create.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
def form_invalid(self, form): def form_invalid(self, form):
print(form.errors) print(form.errors)
return super(AssetAddView, self).form_invalid(form) return super(AssetCreateView, self).form_invalid(form)
class AssetEditView(UpdateView): class AssetUpdateView(UpdateView):
pass pass
@ -48,10 +48,11 @@ class AssetDetailView(DetailView):
template_name = 'assets/asset_detail.html' template_name = 'assets/asset_detail.html'
class AssetGroupAddView(CreateView): class AssetGroupCreateView(CreateView):
model = AssetGroup model = AssetGroup
form_class = AssetGroupForm form_class = AssetGroupForm
template_name = 'assets/assetgroup_add.html' template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
@ -60,13 +61,17 @@ class AssetGroupAddView(CreateView):
'assets': Asset.objects.all(), 'assets': Asset.objects.all(),
} }
kwargs.update(context) kwargs.update(context)
return super(AssetGroupAddView, self).get_context_data(**kwargs) return super(AssetGroupCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
print(form.data)
return super(AssetGroupCreateView, self).form_valid(form)
class AssetGroupListView(ListView): class AssetGroupListView(ListView):
model = AssetGroup model = AssetGroup
context_object_name = 'assetgroups' context_object_name = 'asset_group_list'
template_name = 'assets/assetgroup_list.html' template_name = 'assets/asset_group_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
@ -81,8 +86,20 @@ class AssetGroupDetailView(DetailView):
pass pass
class AssetGroupEditView(UpdateView): class AssetGroupUpdateView(UpdateView):
pass model = AssetGroup
form_class = AssetGroupForm
template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create asset group'),
'assets': Asset.objects.all(),
}
kwargs.update(context)
return super(AssetGroupUpdateView, self).get_context_data(**kwargs)
class AssetGroupDeleteView(DeleteView): class AssetGroupDeleteView(DeleteView):

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-02T14:32:32Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$QU8p6Y6ep8VP$Zhrgn0Issfc8ozrNSdSGmyb3X7lRAbc3EEWdc2RTj/M=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-02T14:32:32Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-16T14:32:32Z", "created_by": "System", "user_permissions": [], "groups": [1]}}] [{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]

View File

@ -1 +1 @@
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-08-24T08:24:34.436Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$MC3vobX7pa0C$l9qIj4UwHqODnj1hMvVy9DjLxbBumZaioQWIFrWQR7c=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-08-24T08:24:34.438Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "date_expired": "2086-08-07T08:24:34.438Z", "created_by": "System", "user_permissions": [], "groups": [1]}}] [{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]

File diff suppressed because one or more lines are too long

View File

@ -75,12 +75,12 @@ INSTALLED_APPS = [
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
] ]
ROOT_URLCONF = 'jumpserver.urls' ROOT_URLCONF = 'jumpserver.urls'
@ -92,6 +92,7 @@ TEMPLATES = [
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
'django.template.context_processors.i18n',
'django.template.context_processors.debug', 'django.template.context_processors.debug',
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
@ -215,7 +216,7 @@ LOGGING = {
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/ # https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en_US' LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Shanghai' TIME_ZONE = 'Asia/Shanghai'

Binary file not shown.

View File

@ -0,0 +1,704 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-09-05 20:18+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: assets/forms.py:20
msgid "Join assetgroups"
msgstr "添加到用户组"
#: assets/models.py:9 assets/models.py:21 assets/models.py:54
#: assets/models.py:76 assets/templates/assets/assetgroup_list.html:12
#: users/models.py:60 users/models.py:107
#: users/templates/users/user_detail.html:69
#: users/templates/users/user_list.html:12
msgid "Name"
msgstr "名称"
#: assets/models.py:10 assets/models.py:29 assets/models.py:42
#: assets/models.py:61 assets/models.py:90 assets/models.py:125
#: assets/models.py:145 users/models.py:122
#: users/templates/users/user_detail.html:101
msgid "Created by"
msgstr "创建者"
#: assets/models.py:11 assets/models.py:30 assets/models.py:44
#: assets/models.py:62 assets/models.py:91 assets/models.py:128
#: assets/models.py:147 assets/templates/assets/assetgroup_list.html:14
#: users/models.py:61 users/models.py:118
#: users/templates/users/user_detail.html:113
msgid "Comment"
msgstr "备注"
#: assets/models.py:22
msgid "Bandwidth"
msgstr "带宽"
#: assets/models.py:23
msgid "Contact"
msgstr "联系人"
#: assets/models.py:24 users/models.py:113
#: users/templates/users/user_detail.html:82
msgid "Phone"
msgstr "手机"
#: assets/models.py:25
msgid "Address"
msgstr "地址"
#: assets/models.py:26
msgid "Network"
msgstr "网络"
#: assets/models.py:27 assets/models.py:127
msgid "Date added"
msgstr "加入日期"
#: assets/models.py:28
msgid "Operator"
msgstr "运营商"
#: assets/models.py:40 assets/models.py:142
msgid "KEY"
msgstr "KEY"
#: assets/models.py:41 assets/models.py:143
msgid "VALUE"
msgstr "VALUE"
#: assets/models.py:55 assets/models.py:77 users/forms.py:12
#: users/models.py:106 users/templates/users/login.html:54
#: users/templates/users/user_detail.html:73
#: users/templates/users/user_edit.html:5
#: users/templates/users/user_list.html:13
msgid "Username"
msgstr "用户名"
#: assets/models.py:56 assets/models.py:78 users/forms.py:13
#: users/templates/users/login.html:57
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_add.html:8 users/templates/users/user_add.html:10
#: users/templates/users/user_edit.html:12
#: users/templates/users/user_edit.html:14
msgid "Password"
msgstr "密码"
#: assets/models.py:57 assets/models.py:80
msgid "SSH private key"
msgstr "ssh密钥"
#: assets/models.py:58 assets/models.py:82
msgid "As default"
msgstr "默认使用"
#: assets/models.py:59 assets/models.py:84
msgid "Auto update pass/key"
msgstr "自动更新密码/密钥"
#: assets/models.py:79
msgid "Protocol"
msgstr "协议"
#: assets/models.py:81
msgid "SSH public key"
msgstr "ssh公钥"
#: assets/models.py:83
msgid "Auto push"
msgstr "自动推送"
#: assets/models.py:85
msgid "Sudo"
msgstr "Sudo"
#: assets/models.py:86
msgid "Shell"
msgstr "Shell"
#: assets/models.py:87 templates/_header_bar.html:35 templates/_nav.html:4
msgid "Home"
msgstr "仪表盘"
#: assets/models.py:88
msgid "Uid"
msgstr "Uid"
#: assets/models.py:101
msgid "IP"
msgstr "IP"
#: assets/models.py:102
msgid "Other IP"
msgstr "其它IP"
#: assets/models.py:103
msgid "Remote card IP"
msgstr "远控卡IP"
#: assets/models.py:104
msgid "Hostname"
msgstr "用户名"
#: assets/models.py:105
msgid "Port"
msgstr "端口"
#: assets/models.py:106
msgid "Asset groups"
msgstr "用户组"
#: assets/models.py:107 assets/models.py:109 templates/_nav.html:24
msgid "Admin user"
msgstr "管理用户"
#: assets/models.py:108
msgid "Admin password"
msgstr "管理员密码"
#: assets/models.py:111 templates/_nav.html:23
msgid "IDC"
msgstr "机房"
#: assets/models.py:112
msgid "Mac address"
msgstr "Mac地址"
#: assets/models.py:113
msgid "Brand"
msgstr "品牌"
#: assets/models.py:114
msgid "CPU"
msgstr "CPU"
#: assets/models.py:115
msgid "Memory"
msgstr "内存"
#: assets/models.py:116
msgid "Disk"
msgstr "硬盘"
#: assets/models.py:117
msgid "OS"
msgstr "操作系统"
#: assets/models.py:118
msgid "Cabinet number"
msgstr "机柜编号"
#: assets/models.py:119
msgid "Cabinet position"
msgstr "机柜层号"
#: assets/models.py:120
msgid "Asset number"
msgstr "资产编号"
#: assets/models.py:121
msgid "Asset status"
msgstr "资产状态"
#: assets/models.py:122
msgid "Asset type"
msgstr "系统类型"
#: assets/models.py:123
msgid "Asset environment"
msgstr "资产环境"
#: assets/models.py:124
msgid "Serial number"
msgstr "序列号"
#: assets/models.py:126
msgid "Is active"
msgstr "是否激活"
#: assets/models.py:144 assets/templates/assets/assetgroup_add.html:35
#: templates/_nav.html:21
msgid "Asset"
msgstr "资产"
#: assets/templates/assets/assetgroup_add.html:16
#: assets/templates/assets/assetgroup_list.html:5 assets/views.py:60
msgid "Create asset group"
msgstr "创建资产组"
#: assets/templates/assets/assetgroup_add.html:37
msgid "Select asset"
msgstr "选择资产"
#: assets/templates/assets/assetgroup_add.html:49
#: users/templates/users/_user.html:70
#: users/templates/users/user_detail.html:162
#: users/templates/users/user_detail.html:170
msgid "Reset"
msgstr "重置"
#: assets/templates/assets/assetgroup_add.html:50
#: assets/templates/assets/assetgroup_list.html:51
#: users/templates/users/_user.html:71
#: users/templates/users/forget_password.html:44
#: users/templates/users/user_list.html:63
msgid "Submit"
msgstr "提交"
#: assets/templates/assets/assetgroup_list.html:13
#: users/templates/users/user_list.html:16
msgid "Asset num"
msgstr "资产数量"
#: assets/templates/assets/assetgroup_list.html:32
#: users/templates/users/user_list.html:44
msgid "Edit"
msgstr "编辑"
#: assets/templates/assets/assetgroup_list.html:33
#: users/templates/users/user_list.html:45
msgid "Delete"
msgstr "删除"
#: assets/templates/assets/assetgroup_list.html:43
#: users/templates/users/user_list.html:55
msgid "Delete selected"
msgstr "批量删除"
#: assets/templates/assets/assetgroup_list.html:44
#: users/templates/users/user_list.html:56
msgid "Update selected"
msgstr "批量更新"
#: assets/templates/assets/assetgroup_list.html:45
#: users/templates/users/user_list.html:57
msgid "Deactive selected"
msgstr "禁用所选"
#: assets/templates/assets/assetgroup_list.html:46
#: users/templates/users/user_list.html:58
msgid "Export selected"
msgstr "批量导出"
#: assets/views.py:59 assets/views.py:74 templates/_nav.html:18
msgid "Assets"
msgstr "资产管理"
#: assets/views.py:75
msgid "Asset group list"
msgstr "资产组列表"
#: templates/_header_bar.html:8 users/templates/users/user_detail.html:29
msgid "Search"
msgstr "搜索"
#: templates/_header_bar.html:14
msgid "Welcome to use Jumpserver system"
msgstr "欢迎使用Jumpserver开源跳板机系统"
#: templates/_header_bar.html:18
msgid "Help"
msgstr "帮助"
#: templates/_nav.html:9 users/views.py:100 users/views.py:113
#: users/views.py:153 users/views.py:170 users/views.py:195 users/views.py:208
msgid "Users"
msgstr "用户管理"
#: templates/_nav.html:12 users/models.py:103
msgid "User"
msgstr "用户"
#: templates/_nav.html:13
msgid "User group"
msgstr "用户组"
#: templates/_nav.html:22
msgid "Asset group"
msgstr "资产组"
#: templates/_nav.html:25
msgid "System user"
msgstr "系统"
#: templates/_nav.html:26
msgid "Label"
msgstr "标签"
#: templates/_nav.html:30
msgid "Perms"
msgstr "权限管理"
#: templates/_nav.html:33
msgid "Perm"
msgstr "权限"
#: templates/_nav.html:36
msgid "Create perm"
msgstr "创建权限"
#: templates/_nav.html:42
msgid "Audits"
msgstr "审计"
#: templates/_nav.html:47
msgid "File"
msgstr "文件"
#: templates/_nav.html:50
msgid "File upload"
msgstr "文件上传"
#: templates/_nav.html:51
msgid "File download"
msgstr "文件下载"
#: templates/_nav.html:56
msgid "Settings"
msgstr "设置"
#: templates/_nav.html:61
msgid "Visit us"
msgstr "访问官网"
#: templates/_user_profile.html:19 users/templates/users/_user.html:63
msgid "Profile"
msgstr "个人信息"
#: templates/_user_profile.html:21
msgid "Logout"
msgstr "注销登录"
#: templates/captcha/image.html:3
msgid "Play CAPTCHA as audio file"
msgstr ""
#: templates/captcha/text_field.html:4
msgid "Captcha"
msgstr "验证码"
#: users/forms.py:31 users/forms.py:50
msgid "Join user groups"
msgstr "添加到用户组"
#: users/models.py:102 users/models.py:225
msgid "Administrator"
msgstr "管理员"
#: users/models.py:108 users/templates/users/user_detail.html:77
msgid "Email"
msgstr "邮件"
#: users/models.py:109 users/templates/users/user_detail.html:181
#: users/templates/users/user_list.html:15
msgid "Usergroup"
msgstr "用户组"
#: users/models.py:110 users/templates/users/user_detail.html:93
#: users/templates/users/user_list.html:14
msgid "Role"
msgstr "角色"
#: users/models.py:111
msgid "Avatar"
msgstr "头像"
#: users/models.py:112 users/templates/users/user_detail.html:88
msgid "Wechat"
msgstr "微信"
#: users/models.py:114 users/templates/users/_user.html:57
msgid "Enable OTP"
msgstr "二次验证"
#: users/models.py:116
msgid "ssh private key"
msgstr "ssh密钥"
#: users/models.py:117
msgid "ssh public key"
msgstr "ssh公钥"
#: users/models.py:121 users/templates/users/user_detail.html:97
msgid "Date expired"
msgstr "失效日期"
#: users/models.py:228
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
#: users/models.py:229
msgid "System"
msgstr "系统"
#: users/templates/users/_user.html:17 users/templates/users/user_list.html:5
#: users/views.py:113
msgid "Create user"
msgstr "创建用户"
#: users/templates/users/_user.html:33
msgid "Account"
msgstr "账户"
#: users/templates/users/_user.html:43
msgid "Security and Role"
msgstr "角色安全"
#: users/templates/users/forget_password.html:26
msgid "Forget password"
msgstr "忘记密码"
#: users/templates/users/forget_password.html:33
msgid "Input your email, that will send a mail to your"
msgstr "输入您的邮箱, 将会发一封重置短信邮件到您的邮箱中"
#: users/templates/users/login.html:42 users/templates/users/login.html:62
msgid "Login"
msgstr "登录"
#: users/templates/users/login.html:47
msgid "Captcha invalid"
msgstr "验证码错误"
#: users/templates/users/reset_password.html:45
#: users/templates/users/user_detail.html:159 users/utils.py:98
msgid "Reset password"
msgstr "重置密码"
#: users/templates/users/reset_password.html:55
msgid "Password again"
msgstr "再次输入密码"
#: users/templates/users/reset_password.html:57
msgid "Setting"
msgstr "设置"
#: users/templates/users/user_add.html:12
msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_delete_confirm.html:6
msgid "Confirm delete"
msgstr "确认删除"
#: users/templates/users/user_detail.html:18 users/views.py:170
msgid "User detail"
msgstr "用户详情"
#: users/templates/users/user_detail.html:20
msgid "User assets"
msgstr "用户资产"
#: users/templates/users/user_detail.html:21
msgid "User log"
msgstr "登录日志"
#: users/templates/users/user_detail.html:105
msgid "Date joined"
msgstr "创建日期"
#: users/templates/users/user_detail.html:109
msgid "Last login"
msgstr "最后登录"
#: users/templates/users/user_detail.html:124
msgid "Quick modify"
msgstr "快速修改"
#: users/templates/users/user_detail.html:167
msgid "Reset ssh key"
msgstr "重置密钥"
#: users/templates/users/user_detail.html:189
msgid "Select usergroups"
msgstr "选择用户组"
#: users/templates/users/user_detail.html:198
msgid "Add"
msgstr "添加"
#: users/templates/users/user_list.html:17
msgid "Active"
msgstr "激活"
#: users/utils.py:47
msgid "Begin to generate ssh private key ..."
msgstr "开始生成ssh密钥"
#: users/utils.py:59
msgid "Finish to generate ssh private key ..."
msgstr "生成ssh密钥成功"
#: users/utils.py:63
msgid "These is error when generate ssh key."
msgstr "创建密钥失败"
#: users/utils.py:67
msgid "Create account successfully"
msgstr "创建账户成功"
#: users/utils.py:69
#, python-format
msgid ""
"\n"
" Hello %(name)s:\n"
" </br>\n"
" Your account has been created successfully\n"
" </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
"here to set your password</a>\n"
" </br>\n"
" This link is valid for 1 hour. After it expires, <a href="
"\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n"
"\n"
" </br>\n"
" "
msgstr ""
"\n"
" 你好 %(name)s:\n"
" </br>\n"
" 恭喜您,您的账号已经创建成功 </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这"
"里设置密码</a> </br>\n"
" 这个链接有效期1小时, 超过时间您可以 <a href=\"%(forget_password_url)s?"
"email=%(email)s\">重新申请</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n"
"\n"
" </br>\n"
" "
#: users/utils.py:100
#, python-format
msgid ""
"\n"
" Hello %(name)s:\n"
" </br>\n"
" Please click the link below to reset your password, if not your request, "
"concern your account security\n"
" </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
"here reset password</a>\n"
" </br>\n"
" This link is valid for 1 hour. After it expires, <a href="
"\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n"
"\n"
" </br>\n"
" "
msgstr ""
"\n"
" 您好 %(name)s:\n"
" </br>\n"
" 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n"
" </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这"
"里设置密码 /a>\n"
" </br>\n"
" 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?"
"email=%(email)s\">重新申请</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">直接登录</a>\n"
"\n"
" </br>\n"
" "
#: users/views.py:53
msgid "Username or password invalid"
msgstr "用户名或密码错误"
#: users/views.py:70
msgid "Logout success"
msgstr "退出登录成功"
#: users/views.py:71
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: users/views.py:100
msgid "User list"
msgstr "用户列表"
#: users/views.py:109
#, python-format
msgid "Create user<a href=\"%s\">%s</a> success."
msgstr "创建用户<a href=\"%s\">%s</a> 成功"
#: users/views.py:153
msgid "Edit user"
msgstr "编辑用户"
#: users/views.py:195
msgid "Usergroup list"
msgstr "用户组列表"
#: users/views.py:208
msgid "Create usergroup"
msgstr "创建用户组"
#: users/views.py:240
msgid "Email address invalid, input again"
msgstr "邮箱地址错误,重新输入"
#: users/views.py:251
msgid "Send reset password message"
msgstr "发送重置密码邮件"
#: users/views.py:252
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views.py:264
msgid "Reset password success"
msgstr "重置密码成功"
#: users/views.py:265
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
#: users/views.py:281 users/views.py:294
msgid "Token invalid or expired"
msgstr "Token错误或失效"
#: users/views.py:290
msgid "Password not same"
msgstr "密码不一致"
#, fuzzy
#~| msgid "Asset groups"
#~ msgid "Assetgroup"
#~ msgstr "用户组"

View File

@ -1,515 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-09-04 17:31+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: assets/models.py:9 assets/models.py:21
msgid "Name"
msgstr "名称"
#: assets/models.py:10 assets/models.py:29 assets/models.py:71
msgid "Created by"
msgstr "创建者"
#: assets/models.py:11 assets/models.py:30 assets/models.py:74
msgid "Comment"
msgstr "备注"
#: assets/models.py:22
msgid "Bandwidth"
msgstr "带宽"
#: assets/models.py:23
msgid "Contact"
msgstr "联系人"
#: assets/models.py:24
msgid "Phone"
msgstr "手机"
#: assets/models.py:25
msgid "Address"
msgstr "地址"
#: assets/models.py:26
msgid "Network"
msgstr "网络"
#: assets/models.py:27 assets/models.py:73
msgid "Date added"
msgstr "加入日期"
#: assets/models.py:28
msgid "Operator"
msgstr "运营商"
#: assets/models.py:37 assets/models.py:54 templates/_nav.html:23
msgid "IDC"
msgstr "机房"
#: assets/models.py:46
msgid "IP"
msgstr ""
#: assets/models.py:47
msgid "Other IP"
msgstr ""
#: assets/models.py:48
msgid "Remote card IP"
msgstr ""
#: assets/models.py:49
msgid "Hostname"
msgstr "用户名"
#: assets/models.py:50
msgid "Port"
msgstr "端口"
#: assets/models.py:51
msgid "Asset groups"
msgstr "用户组"
#: assets/models.py:52
#, fuzzy
#| msgid "Edit user"
msgid "Admin user"
msgstr "编辑用户"
#: assets/models.py:53
msgid "Admin password"
msgstr "管理员密码"
#: assets/models.py:55
msgid "Mac address"
msgstr "Mac地址"
#: assets/models.py:56
msgid "Brand"
msgstr "品牌"
#: assets/models.py:57
msgid "CPU"
msgstr "CPU"
#: assets/models.py:58
msgid "Memory"
msgstr "内存"
#: assets/models.py:59
msgid "Disk"
msgstr "硬盘"
#: assets/models.py:60
msgid "OS"
msgstr "操作系统"
#: assets/models.py:61
msgid "Cabinet number"
msgstr "机柜编号"
#: assets/models.py:62
msgid "Cabinet position"
msgstr "机柜层号"
#: assets/models.py:63
msgid "Asset number"
msgstr "资产编号"
#: assets/models.py:65
msgid "Asset status"
msgstr "资产状态"
#: assets/models.py:67
msgid "Asset type"
msgstr "系统类型"
#: assets/models.py:69
msgid "Asset environment"
msgstr "资产环境"
#: assets/models.py:70
msgid "Serial number"
msgstr "序列号"
#: assets/models.py:72
msgid "Is active"
msgstr "是否激活"
#: templates/_header_bar.html:8
msgid "Search"
msgstr "搜索"
#: templates/_header_bar.html:14
msgid "Welcome use Jumpserver system"
msgstr "欢迎使用Jumpserver开源跳板机系统"
#: templates/_header_bar.html:18
msgid "Help"
msgstr "帮助"
#: templates/_header_bar.html:35 templates/_nav.html:4
msgid "Home"
msgstr "仪表盘"
#: templates/_nav.html:9
msgid "Users"
msgstr "用户管理"
#: templates/_nav.html:12
msgid "User"
msgstr "用户"
#: templates/_nav.html:13
msgid "Usergroup"
msgstr "用户组"
#: templates/_nav.html:18
msgid "Assets"
msgstr "资产管理"
#: templates/_nav.html:21
msgid "Asset"
msgstr "资产"
#: templates/_nav.html:22
msgid "Assetgroup"
msgstr "用户组"
#: templates/_nav.html:24
#, fuzzy
#| msgid "Asset admin"
msgid "Assetadmin"
msgstr "管理用户"
#: templates/_nav.html:25
#, fuzzy
#| msgid "Asset user"
msgid "Assetuser"
msgstr "系统用户"
#: templates/_nav.html:26
msgid "Label"
msgstr "标签"
#: templates/_nav.html:30
msgid "Perms"
msgstr "权限管理"
#: templates/_nav.html:33
msgid "Perm"
msgstr "权限"
#: templates/_nav.html:36
msgid "Create perm"
msgstr "创建权限"
#: templates/_nav.html:42
msgid "Audits"
msgstr "审计"
#: templates/_nav.html:47
msgid "File"
msgstr "文件"
#: templates/_nav.html:50
msgid "File upload"
msgstr "文件上传"
#: templates/_nav.html:51
msgid "File download"
msgstr "文件下载"
#: templates/_nav.html:56
msgid "Settings"
msgstr "设置"
#: templates/_nav.html:61
msgid "Visit us"
msgstr "访问官网"
#: templates/_user_profile.html:19
msgid "Profile"
msgstr "个人信息"
#: templates/_user_profile.html:21
msgid "Logout"
msgstr "注销登录"
#: templates/captcha/image.html:3
msgid "Play CAPTCHA as audio file"
msgstr ""
#~ msgid "Asset user"
#~ msgstr "系统用户"
#~ msgid "Password"
#~ msgstr "密码"
#~ msgid "Join usergroups"
#~ msgstr "添加到用户组"
#~ msgid "Administrator"
#~ msgstr "管理员"
#~ msgid "Email"
#~ msgstr "邮件"
#~ msgid "Role"
#~ msgstr "角色"
#~ msgid "Avatar"
#~ msgstr "头像"
#~ msgid "Wechat"
#~ msgstr "微信"
#~ msgid "Enable OTP"
#~ msgstr "二次验证"
#~ msgid "ssh private key"
#~ msgstr "ssh密钥"
#~ msgid "ssh public key"
#~ msgstr "ssh公钥"
#~ msgid "Date expired"
#~ msgstr "失效日期"
#~ msgid "Administrator is the super user of system"
#~ msgstr "Administrator是初始的超级管理员"
#~ msgid "System"
#~ msgstr "系统"
#~ msgid "Create user"
#~ msgstr "创建用户"
#~ msgid "Account"
#~ msgstr "账户"
#~ msgid "Security and Role"
#~ msgstr "角色安全"
#~ msgid "Reset"
#~ msgstr "重置"
#~ msgid "Commit"
#~ msgstr "提交"
#~ msgid "Forget password"
#~ msgstr "忘记密码"
#~ msgid "Input your email, that will send a mail to your"
#~ msgstr "输入您的邮箱, 将会发一封重置短信邮件到您的邮箱中"
#~ msgid "Login"
#~ msgstr "登录"
#~ msgid "Captcha invalid"
#~ msgstr "验证码错误"
#~ msgid "Password again"
#~ msgstr "再次输入密码"
#~ msgid "Setting"
#~ msgstr "设置"
#~ msgid "Reset link will be generated and sent to the user. "
#~ msgstr "生成重置密码连接,通过邮件发送给用户"
#~ msgid "Confirm delete"
#~ msgstr "确认删除"
#~ msgid "User detail"
#~ msgstr "用户详情"
#~ msgid "User assets"
#~ msgstr "用户资产"
#~ msgid "User log"
#~ msgstr "登录日志"
#~ msgid "Last login"
#~ msgstr "最后登录"
#~ msgid "Quick modify"
#~ msgstr "快速修改"
#~ msgid "Reset ssh key"
#~ msgstr "重置密钥"
#~ msgid "Select usergroups"
#~ msgstr "选择用户组"
#~ msgid "Add"
#~ msgstr "添加"
#~ msgid "Edit"
#~ msgstr "编辑"
#~ msgid "Delete"
#~ msgstr "删除"
#~ msgid "Delete selected"
#~ msgstr "批量删除"
#~ msgid "Update selected"
#~ msgstr "批量更新"
#~ msgid "Deactive selected"
#~ msgstr "禁用所选"
#~ msgid "Export selected"
#~ msgstr "批量导出"
#~ msgid "Begin to generate ssh private key ..."
#~ msgstr "开始生成ssh密钥"
#~ msgid "Finish to generate ssh private key ..."
#~ msgstr "生成ssh密钥成功"
#~ msgid "These is error when generate ssh key."
#~ msgstr "创建密钥失败"
#~ msgid "Create account successfully"
#~ msgstr "创建账户成功"
#~ msgid ""
#~ "\n"
#~ " Hello %(name)s:\n"
#~ " </br>\n"
#~ " Your account has been created successfully\n"
#~ " </br>\n"
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
#~ "here to set your password</a>\n"
#~ " </br>\n"
#~ " This link is valid for 1 hour. After it expires, <a href="
#~ "\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " ---\n"
#~ "\n"
#~ " </br>\n"
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " "
#~ msgstr ""
#~ "\n"
#~ " 你好 %(name)s:\n"
#~ " </br>\n"
#~ " 恭喜您,您的账号已经创建成功 </br>\n"
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点"
#~ "击这里设置密码</a> </br>\n"
#~ " 这个链接有效期1小时, 超过时间您可以 <a href=\"%(forget_password_url)s?"
#~ "email=%(email)s\">重新申请</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " ---\n"
#~ "\n"
#~ " </br>\n"
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " "
#~ msgid ""
#~ "\n"
#~ " Hello %(name)s:\n"
#~ " </br>\n"
#~ " Please click the link below to reset your password, if not your "
#~ "request, concern your account security\n"
#~ " </br>\n"
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
#~ "here reset password</a>\n"
#~ " </br>\n"
#~ " This link is valid for 1 hour. After it expires, <a href="
#~ "\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " ---\n"
#~ "\n"
#~ " </br>\n"
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " "
#~ msgstr ""
#~ "\n"
#~ " 您好 %(name)s:\n"
#~ " </br>\n"
#~ " 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n"
#~ " </br>\n"
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击"
#~ "这里设置密码 /a>\n"
#~ " </br>\n"
#~ " 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?"
#~ "email=%(email)s\">重新申请</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " ---\n"
#~ "\n"
#~ " </br>\n"
#~ " <a href=\"%(login_url)s\">直接登录</a>\n"
#~ "\n"
#~ " </br>\n"
#~ " "
#~ msgid "Username or password invalid"
#~ msgstr "用户名或密码错误"
#~ msgid "Logout success"
#~ msgstr "退出登录成功"
#~ msgid "Logout success, return login page"
#~ msgstr "退出登录成功,返回到登录页面"
#~ msgid "User list"
#~ msgstr "用户列表"
#~ msgid "Create user<a href=\"%s\">%s</a> success."
#~ msgstr "创建用户<a href=\"%s\">%s</a> 成功"
#~ msgid "Usergroup list"
#~ msgstr "用户组列表"
#~ msgid "Create usergroup"
#~ msgstr "创建用户组"
#~ msgid "Email address invalid, input again"
#~ msgstr "邮箱地址错误,重新输入"
#~ msgid "Send reset password message"
#~ msgstr "发送重置密码邮件"
#~ msgid "Send reset password mail success, login your mail box and follow it "
#~ msgstr ""
#~ "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#~ msgid "Reset password success"
#~ msgstr "重置密码成功"
#~ msgid "Reset password success, return to login page"
#~ msgstr "重置密码成功,返回到登录页面"
#~ msgid "Token invalid or expired"
#~ msgstr "Token错误或失效"
#~ msgid "Password not same"
#~ msgstr "密码不一致"

View File

@ -1,8 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os
import sys import sys
import errno
if __name__ == "__main__": if __name__ == "__main__":
try:
os.makedirs('../logs')
except:
pass
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line

View File

@ -6,18 +6,19 @@
<script src="{% static "js/inspinia.js" %}"></script> <script src="{% static "js/inspinia.js" %}"></script>
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}"></script>
<!-- active menu -->
<script> <script>
<!-- active menu -->
var url_array = document.location.pathname.split("/"); var url_array = document.location.pathname.split("/");
s1 = url_array[1]; app = url_array[1];
s2 = url_array[2]; resource = url_array[2];
if (s1 == ''){ if (app == ''){
$('#index').addClass('active') $('#index').addClass('active')
} else { } else {
$("#"+s1).addClass('active'); $("#"+app).addClass('active');
$('#'+s1+' .'+s2).addClass('active'); $('#'+app+' #'+resource).addClass('active');
} }
<!-- ajax set cookie -->
function getCookie(name) { function getCookie(name) {
var cookieValue = null; var cookieValue = null;
if (document.cookie && document.cookie !== '') { if (document.cookie && document.cookie !== '') {
@ -46,8 +47,10 @@
beforeSend: function(xhr, settings) { beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken); xhr.setRequestHeader("X-CSRFToken", csrftoken);
{# xhr.setRequestHeader("sessionid", sessionid);#}
} }
} }
}); });
<!-- textarea rows -->
$('textarea').attr('rows', 5)
</script> </script>

View File

@ -11,7 +11,7 @@
</div> </div>
<ul class="nav navbar-top-links navbar-right"> <ul class="nav navbar-top-links navbar-right">
<li> <li>
<span class="m-r-sm text-muted welcome-message">{% trans 'Welcome use Jumpserver system' %}</span> <span class="m-r-sm text-muted welcome-message">{% trans 'Welcome to use Jumpserver system' %}</span>
</li> </li>
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle count-info" data-toggle="dropdown" href="#"> <a class="dropdown-toggle count-info" data-toggle="dropdown" href="#">

View File

@ -9,30 +9,30 @@
<i class="fa fa-group"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span> <i class="fa fa-group"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level active"> <ul class="nav nav-second-level active">
<li class="users"><a href="{% url 'users:user-list' %}">{% trans 'User' %}</a></li> <li id="user"><a href="{% url 'users:user-list' %}">{% trans 'User' %}</a></li>
<li class="usergroups"><a href="{% url 'users:usergroup-list' %}">{% trans 'Usergroup' %}</a></li> <li id="user-group"><a href="{% url 'users:user-group-list' %}">{% trans 'User group' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="assets">
<a> <a>
<i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span> <i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="{% url 'assets:asset-list' %}"><a href="">{% trans 'Asset' %}</a></li> <li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset' %}</a></li>
<li class=""><a href="{% url 'assets:assetgroup-list' %}">{% trans 'Assetgroup' %}</a></li> <li id="asset-group"><a href="{% url 'assets:asset-group-list' %}">{% trans 'Asset group' %}</a></li>
<li class=""><a href="">{% trans 'IDC' %}</a></li> <li id="idc"><a href="">{% trans 'IDC' %}</a></li>
<li class=""><a href="">{% trans 'Assetadmin' %}</a></li> <li id="admin-user"><a href="">{% trans 'Admin user' %}</a></li>
<li class=""><a href="">{% trans 'Assetuser' %}</a></li> <li id="system-user"><a href="">{% trans 'System user' %}</a></li>
<li class=""><a href="">{% trans 'Label' %}</a></li> <li id=""><a href="">{% trans 'Label' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="sudo"> <li id="sudo">
<a class="sudo" href="">{% trans 'Perm' %}</a> <a class="sudo" href="">{% trans 'Perm' %}</a>
</li> </li>
<li class="role"> <li id="role">
<a href="">{% trans 'Create perm' %}</a> <a href="">{% trans 'Create perm' %}</a>
</li> </li>
</ul> </ul>
@ -47,8 +47,8 @@
<i class="fa fa-download"></i> <span class="nav-label">{% trans 'File' %}</span><span class="fa arrow"></span> <i class="fa fa-download"></i> <span class="nav-label">{% trans 'File' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="upload"><a href="">{% trans 'File upload' %}</a></li> <li id="upload"><a href="">{% trans 'File upload' %}</a></li>
<li class="download"><a href="">{% trans 'File download' %}</a></li> <li id="download"><a href="">{% trans 'File download' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">

View File

@ -11,7 +11,7 @@
<strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong> <strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong>
</span> </span>
<span class="text-muted text-xs block"> <span class="text-muted text-xs block">
{{ request.user.get_role_display | default:"{% trans 'User' %}" }}<b class="caret"></b> {{ request.user.get_role_display | default:_('User') }}<b class="caret"></b>
</span> </span>
</span> </span>
</a> </a>

View File

@ -1,7 +1,7 @@
{% load i18n %}
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<input autocomplete="off" id="{{id}}_1" class="form-control" name="{{name}}_1" type="text" /> <input autocomplete="off" id="{{id}}_1" class="form-control" name="{{name}}_1" placeholder="{% trans 'Captcha' %}" type="text" />
<span class="red-fonts" id="captcha-error" style="display: none">验证码错误</span>
</div> </div>
</div> </div>
</br> </br>

View File

@ -14,7 +14,7 @@ class UserLoginForm(forms.Form):
captcha = CaptchaField() captcha = CaptchaField()
class UserAddForm(ModelForm): class UserCreateForm(ModelForm):
class Meta: class Meta:
model = User model = User
fields = [ fields = [
@ -28,7 +28,7 @@ class UserAddForm(ModelForm):
} }
widgets = { widgets = {
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join usergroups')}), 'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join user groups')}),
} }

View File

@ -1,379 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-09-04 17:31+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: users/forms.py:12 users/models.py:106 users/templates/users/login.html:57
#: users/templates/users/user_detail.html:73
#: users/templates/users/user_edit.html:5
#: users/templates/users/user_list.html:13
msgid "Username"
msgstr ""
#: users/forms.py:13 users/templates/users/login.html:60
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_add.html:8 users/templates/users/user_add.html:10
#: users/templates/users/user_edit.html:12
#: users/templates/users/user_edit.html:14
msgid "Password"
msgstr ""
#: users/forms.py:31 users/forms.py:50
msgid "Join usergroups"
msgstr ""
#: users/models.py:60 users/models.py:107
#: users/templates/users/user_detail.html:69
#: users/templates/users/user_list.html:12
msgid "Name"
msgstr ""
#: users/models.py:61 users/models.py:118
#: users/templates/users/user_detail.html:113
msgid "Comment"
msgstr ""
#: users/models.py:102 users/models.py:225
msgid "Administrator"
msgstr ""
#: users/models.py:103
msgid "User"
msgstr ""
#: users/models.py:108 users/templates/users/user_detail.html:77
msgid "Email"
msgstr ""
#: users/models.py:109 users/templates/users/user_detail.html:181
#: users/templates/users/user_list.html:15
msgid "Usergroup"
msgstr ""
#: users/models.py:110 users/templates/users/user_detail.html:93
#: users/templates/users/user_list.html:14
msgid "Role"
msgstr ""
#: users/models.py:111
msgid "Avatar"
msgstr ""
#: users/models.py:112 users/templates/users/user_detail.html:88
msgid "Wechat"
msgstr ""
#: users/models.py:113 users/templates/users/user_detail.html:82
msgid "Phone"
msgstr ""
#: users/models.py:114 users/templates/users/_user.html:56
msgid "Enable OTP"
msgstr ""
#: users/models.py:116
msgid "ssh private key"
msgstr ""
#: users/models.py:117
msgid "ssh public key"
msgstr ""
#: users/models.py:121 users/templates/users/user_detail.html:97
msgid "Date expired"
msgstr ""
#: users/models.py:122 users/templates/users/user_detail.html:101
msgid "Created by"
msgstr ""
#: users/models.py:228
msgid "Administrator is the super user of system"
msgstr ""
#: users/models.py:229
msgid "System"
msgstr ""
#: users/templates/users/_user.html:17 users/templates/users/user_list.html:5
#: users/views.py:113
msgid "Create user"
msgstr ""
#: users/templates/users/_user.html:33
msgid "Account"
msgstr ""
#: users/templates/users/_user.html:43
msgid "Security and Role"
msgstr ""
#: users/templates/users/_user.html:62
msgid "Profile"
msgstr ""
#: users/templates/users/_user.html:69
#: users/templates/users/user_detail.html:162
#: users/templates/users/user_detail.html:170
msgid "Reset"
msgstr ""
#: users/templates/users/_user.html:70
#: users/templates/users/forget_password.html:44
#: users/templates/users/user_list.html:63
msgid "Commit"
msgstr ""
#: users/templates/users/forget_password.html:26
msgid "Forget password"
msgstr ""
#: users/templates/users/forget_password.html:33
msgid "Input your email, that will send a mail to your"
msgstr ""
#: users/templates/users/login.html:45 users/templates/users/login.html:65
msgid "Login"
msgstr ""
#: users/templates/users/login.html:50
msgid "Captcha invalid"
msgstr ""
#: users/templates/users/reset_password.html:45
#: users/templates/users/user_detail.html:159 users/utils.py:98
msgid "Reset password"
msgstr ""
#: users/templates/users/reset_password.html:55
msgid "Password again"
msgstr ""
#: users/templates/users/reset_password.html:57
msgid "Setting"
msgstr ""
#: users/templates/users/user_add.html:12
msgid "Reset link will be generated and sent to the user. "
msgstr ""
#: users/templates/users/user_delete_confirm.html:6
msgid "Confirm delete"
msgstr ""
#: users/templates/users/user_detail.html:18 users/views.py:173
msgid "User detail"
msgstr ""
#: users/templates/users/user_detail.html:20
msgid "User assets"
msgstr ""
#: users/templates/users/user_detail.html:21
msgid "User log"
msgstr ""
#: users/templates/users/user_detail.html:29
msgid "Search"
msgstr ""
#: users/templates/users/user_detail.html:105
msgid "Date joined"
msgstr ""
#: users/templates/users/user_detail.html:109
msgid "Last login"
msgstr ""
#: users/templates/users/user_detail.html:124
msgid "Quick modify"
msgstr ""
#: users/templates/users/user_detail.html:167
msgid "Reset ssh key"
msgstr ""
#: users/templates/users/user_detail.html:189
msgid "Select usergroups"
msgstr ""
#: users/templates/users/user_detail.html:198
msgid "Add"
msgstr ""
#: users/templates/users/user_list.html:16
msgid "Asset num"
msgstr ""
#: users/templates/users/user_list.html:17
msgid "Active"
msgstr ""
#: users/templates/users/user_list.html:44
msgid "Edit"
msgstr ""
#: users/templates/users/user_list.html:45
msgid "Delete"
msgstr ""
#: users/templates/users/user_list.html:55
msgid "Delete selected"
msgstr ""
#: users/templates/users/user_list.html:56
msgid "Update selected"
msgstr ""
#: users/templates/users/user_list.html:57
msgid "Deactive selected"
msgstr ""
#: users/templates/users/user_list.html:58
msgid "Export selected"
msgstr ""
#: users/utils.py:47
msgid "Begin to generate ssh private key ..."
msgstr ""
#: users/utils.py:59
msgid "Finish to generate ssh private key ..."
msgstr ""
#: users/utils.py:63
msgid "These is error when generate ssh key."
msgstr ""
#: users/utils.py:67
msgid "Create account successfully"
msgstr ""
#: users/utils.py:69
#, python-format
msgid ""
"\n"
" Hello %(name)s:\n"
" </br>\n"
" Your account has been created successfully\n"
" </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
"here to set your password</a>\n"
" </br>\n"
" This link is valid for 1 hour. After it expires, <a href="
"\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n"
"\n"
" </br>\n"
" "
msgstr ""
#: users/utils.py:100
#, python-format
msgid ""
"\n"
" Hello %(name)s:\n"
" </br>\n"
" Please click the link below to reset your password, if not your request, "
"concern your account security\n"
" </br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
"here reset password</a>\n"
" </br>\n"
" This link is valid for 1 hour. After it expires, <a href="
"\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
"\n"
" </br>\n"
" ---\n"
"\n"
" </br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n"
"\n"
" </br>\n"
" "
msgstr ""
#: users/views.py:53
msgid "Username or password invalid"
msgstr ""
#: users/views.py:70
msgid "Logout success"
msgstr ""
#: users/views.py:71
msgid "Logout success, return login page"
msgstr ""
#: users/views.py:100 users/views.py:113 users/views.py:155 users/views.py:173
#: users/views.py:197 users/views.py:210
msgid "Users"
msgstr ""
#: users/views.py:100
msgid "User list"
msgstr ""
#: users/views.py:109
#, python-format
msgid "Create user<a href=\"%s\">%s</a> success."
msgstr ""
#: users/views.py:155
msgid "Edit user"
msgstr ""
#: users/views.py:197
msgid "Usergroup list"
msgstr ""
#: users/views.py:210
msgid "Create usergroup"
msgstr ""
#: users/views.py:242
msgid "Email address invalid, input again"
msgstr ""
#: users/views.py:253
msgid "Send reset password message"
msgstr ""
#: users/views.py:254
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
#: users/views.py:266
msgid "Reset password success"
msgstr ""
#: users/views.py:267
msgid "Reset password success, return to login page"
msgstr ""
#: users/views.py:283 users/views.py:296
msgid "Token invalid or expired"
msgstr ""
#: users/views.py:292
msgid "Password not same"
msgstr ""

View File

@ -66,7 +66,7 @@ class UserGroup(models.Model):
return self.name return self.name
class Meta: class Meta:
db_table = 'usergroup' db_table = 'user-group'
@classmethod @classmethod
def initial(cls): def initial(cls):

View File

@ -7,7 +7,7 @@ from .models import User, UserGroup
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
groups = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='users:usergroup-detail-api') groups = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='users:user-group-detail-api')
class Meta: class Meta:
model = User model = User

View File

@ -47,11 +47,12 @@
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group date"> <div class="input-group date">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span> <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}"> <input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'Y-m-d' }}">
</div> </div>
<span class="help-block ">{{ form.date_expired.errors }}</span> <span class="help-block ">{{ form.date_expired.errors }}</span>
</div> </div>
</div> </div>
{# {{ form.date_expired|bootstrap_horizontal }}#}
<div class="form-group"> <div class="form-group">
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label> <label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
<div class="col-sm-8"> <div class="col-sm-8">
@ -67,7 +68,7 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button> <button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Commit' %}</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div> </div>
</div> </div>
</form> </form>
@ -84,6 +85,7 @@
$('.select2').select2(); $('.select2').select2();
$('.input-group.date').datepicker({ $('.input-group.date').datepicker({
format: "yyyy-mm-dd",
todayBtn: "linked", todayBtn: "linked",
keyboardNavigation: false, keyboardNavigation: false,
forceParse: false, forceParse: false,

View File

@ -41,7 +41,7 @@
<input type="email" name="email" class="form-control" placeholder="Email address" required=""> <input type="email" name="email" class="form-control" placeholder="Email address" required="">
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Commit' %}</button> <button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Submit' %}</button>
</form> </form>
</div> </div>

View File

@ -13,11 +13,8 @@
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}"></script>
<style> <style>
.captcha { .captcha {
float: right; float: right;
} }
#id_captcha_1 {
}
</style> </style>
</head> </head>

View File

@ -1,5 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load static %} {% load static %}
{% load i18n %}
{% load bootstrap %} {% load bootstrap %}
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
@ -12,7 +13,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>填写用户组信息</h5> <h5>{% trans 'Create user group' %}</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>

View File

@ -1,14 +1,15 @@
{% extends '_list_base.html' %} {% extends '_list_base.html' %}
{% load i18n %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block content_left_head %}
<a href="{% url 'users:usergroup-add' %}" class="btn btn-sm btn-primary "> 添加用户组 </a> <a href="{% url 'users:user-group-create' %}" class="btn btn-sm btn-primary "> 添加用户组 </a>
{% endblock %} {% endblock %}
{% block table_head %} {% block table_head %}
<th class="text-center"> <th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')"> <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th> </th>
<th class="text-center"><a href="{% url 'users:usergroup-list' %}?sort=name">名称</a></th> <th class="text-center"><a href="{% url 'users:user-group-list' %}?sort=name">名称</a></th>
<th class="text-center">用户数量</th> <th class="text-center">用户数量</th>
<th class="text-center">资产数量</th> <th class="text-center">资产数量</th>
<th class="text-center">描述</th> <th class="text-center">描述</th>
@ -16,22 +17,22 @@
{% endblock %} {% endblock %}
{% block table_body %} {% block table_body %}
{% for usergroup in usergroup_list %} {% for user_group in user_group_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"> <td class="text-center">
<input type="checkbox" name="checked" value="{{ usergroup.id }}"> <input type="checkbox" name="checked" value="{{ user_group.id }}">
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'users:usergroup-detail' pk=usergroup.id %}"> <a href="{% url 'users:user-group-detail' pk=user_group.id %}">
{{ usergroup.name }} {{ user_group.name }}
</a> </a>
</td> </td>
<td class="text-center">{{ usergroup.users.all|length }}</td> <td class="text-center">{{ user_group.users.all|length }}</td>
<td class="text-center">数量</td> <td class="text-center">数量</td>
<th class="text-center">{{ usergroup.comment|truncatewords:8 }}</th> <th class="text-center">{{ user_group.comment|truncatewords:8 }}</th>
<td class="text-center"> <td class="text-center">
<a href="{% url 'users:usergroup-edit' pk=usergroup.id %}" class="btn btn-xs btn-info">编辑</a> <a href="{% url 'users:user-group-update' pk=user_group.id %}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'users:usergroup-delete' pk=usergroup.id %}" class="btn btn-xs btn-danger del">删除</a> <a href="{% url 'users:user-group-delete' pk=user_group.id %}" class="btn btn-xs btn-danger del">删除</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block content_left_head %}
<a href="{% url 'users:user-add' %}" class="btn btn-sm btn-primary "> {% trans "Create user" %} </a> <a href="{% url 'users:user-create' %}" class="btn btn-sm btn-primary "> {% trans "Create user" %} </a>
{% endblock %} {% endblock %}
{% block table_head %} {% block table_head %}
@ -41,7 +41,7 @@
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a> <a href="{% url 'users:user-update' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a>
<a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">{% trans 'Delete' %}</a> <a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
@ -60,7 +60,7 @@
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary"> <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Commit' %} {% trans 'Submit' %}
</button> </button>
</div> </div>

View File

@ -54,7 +54,7 @@ class UserAddTests(TestCase):
'date_expired': '2086-08-06 19:12:22', 'date_expired': '2086-08-06 19:12:22',
} }
response = self.client.post(reverse('users:user-add'), data) response = self.client.post(reverse('users:user-create'), data)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response['location'], reverse('users:user-list')) self.assertEqual(response['location'], reverse('users:user-list'))

View File

@ -17,14 +17,14 @@ urlpatterns = [
url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(), name='reset-password-success'), url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(), name='reset-password-success'),
url(r'^user$', views.UserListView.as_view(), name='user-list'), url(r'^user$', views.UserListView.as_view(), name='user-list'),
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'), url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
url(r'^user/add$', views.UserAddView.as_view(), name='user-add'), url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
url(r'^user/(?P<pk>[0-9]+)/edit$', views.UserUpdateView.as_view(), name='user-edit'), url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
url(r'^user/(?P<pk>[0-9]+)/delete$', views.UserDeleteView.as_view(), name='user-delete'), url(r'^user/(?P<pk>[0-9]+)/delete$', views.UserDeleteView.as_view(), name='user-delete'),
url(r'^usergroup$', views.UserGroupListView.as_view(), name='usergroup-list'), url(r'^user-group$', views.UserGroupListView.as_view(), name='user-group-list'),
url(r'^usergroup/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='usergroup-detail'), url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
url(r'^usergroup/add/$', views.UserGroupAddView.as_view(), name='usergroup-add'), url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
url(r'^usergroup/(?P<pk>[0-9]+)/edit$', views.UserGroupUpdateView.as_view(), name='usergroup-edit'), url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'),
url(r'^usergroup/(?P<pk>[0-9]+)/delete$', views.UserGroupDeleteView.as_view(), name='usergroup-delete'), url(r'^user-group/(?P<pk>[0-9]+)/delete$', views.UserGroupDeleteView.as_view(), name='user-group-delete'),
] ]
@ -32,6 +32,6 @@ urlpatterns += [
url(r'^v1/users$', api.UserListAddApi.as_view(), name='user-list-api'), url(r'^v1/users$', api.UserListAddApi.as_view(), name='user-list-api'),
url(r'^v1/users/(?P<pk>[0-9]+)$', api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'), url(r'^v1/users/(?P<pk>[0-9]+)$', api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
url(r'^v1/users/(?P<pk>[0-9]+)/active$', api.UserActiveApi.as_view(), name='user-active-api'), url(r'^v1/users/(?P<pk>[0-9]+)/active$', api.UserActiveApi.as_view(), name='user-active-api'),
url(r'^v1/usergroups$', api.UserGroupListAddApi.as_view(), name='usergroup-list-api'), url(r'^v1/usergroups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
url(r'^v1/usergroups/(?P<pk>[0-9]+)$', api.UserGroupDetailDeleteUpdateApi.as_view(), name='usergroup-detail-api'), url(r'^v1/usergroups/(?P<pk>[0-9]+)$', api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
] ]

View File

@ -20,7 +20,7 @@ from django.contrib.auth import views as auth_view, authenticate, login, logout
from common.utils import get_object_or_none from common.utils import get_object_or_none
from .models import User, UserGroup from .models import User, UserGroup
from .forms import UserAddForm, UserUpdateForm, UserGroupForm, UserLoginForm from .forms import UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm
from .utils import AdminUserRequiredMixin, ssh_key_gen, user_add_success_next, send_reset_password_mail from .utils import AdminUserRequiredMixin, ssh_key_gen, user_add_success_next, send_reset_password_mail
@ -101,15 +101,15 @@ class UserListView(AdminUserRequiredMixin, ListView):
return context return context
class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = User model = User
form_class = UserAddForm form_class = UserCreateForm
template_name = 'users/user_add.html' template_name = 'users/user_create.html'
success_url = reverse_lazy('users:user-list') success_url = reverse_lazy('users:user-list')
success_message = _('Create user<a href="%s">%s</a> success.') success_message = _('Create user<a href="%s">%s</a> success.')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserAddView, self).get_context_data(**kwargs) context = super(UserCreateView, self).get_context_data(**kwargs)
context.update({'app': _('Users'), 'action': _('Create user')}) context.update({'app': _('Users'), 'action': _('Create user')})
return context return context
@ -117,10 +117,8 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
user = form.save(commit=False) user = form.save(commit=False)
user.created_by = self.request.user.username or 'System' user.created_by = self.request.user.username or 'System'
user.save() user.save()
user_add_success_next(user) user_add_success_next(user)
return super(UserCreateView, self).form_valid(form)
return super(UserAddView, self).form_valid(form)
def get_success_message(self, cleaned_data): def get_success_message(self, cleaned_data):
return self.success_message % ( return self.success_message % (
@ -132,7 +130,7 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
class UserUpdateView(AdminUserRequiredMixin, UpdateView): class UserUpdateView(AdminUserRequiredMixin, UpdateView):
model = User model = User
form_class = UserUpdateForm form_class = UserUpdateForm
template_name = 'users/user_edit.html' template_name = 'users/user_update.html'
context_object_name = 'user' context_object_name = 'user'
success_url = reverse_lazy('users:user-list') success_url = reverse_lazy('users:user-list')
@ -177,8 +175,8 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
class UserGroupListView(AdminUserRequiredMixin, ListView): class UserGroupListView(AdminUserRequiredMixin, ListView):
model = UserGroup model = UserGroup
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
context_object_name = 'usergroup_list' context_object_name = 'user_group_list'
template_name = 'users/usergroup_list.html' template_name = 'users/user_group_list.html'
ordering = '-date_added' ordering = '-date_added'
def get_queryset(self): def get_queryset(self):
@ -198,26 +196,26 @@ class UserGroupListView(AdminUserRequiredMixin, ListView):
return context return context
class UserGroupAddView(AdminUserRequiredMixin, CreateView): class UserGroupCreateView(AdminUserRequiredMixin, CreateView):
model = UserGroup model = UserGroup
form_class = UserGroupForm form_class = UserGroupForm
template_name = 'users/usergroup_add.html' template_name = 'users/user_group_create.html'
success_url = reverse_lazy('users:usergroup-list') success_url = reverse_lazy('users:user-group-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserGroupAddView, self).get_context_data(**kwargs) context = super(UserGroupCreateView, self).get_context_data(**kwargs)
users = User.objects.all() users = User.objects.all()
context.update({'app': _('Users'), 'action': _('Create usergroup'), 'users': users}) context.update({'app': _('Users'), 'action': _('Create user group'), 'users': users})
return context return context
def form_valid(self, form): def form_valid(self, form):
usergroup = form.save() user_group = form.save()
users_id_list = self.request.POST.getlist('users', []) users_id_list = self.request.POST.getlist('users', [])
users = [get_object_or_404(User, id=user_id) for user_id in users_id_list] users = [get_object_or_404(User, id=user_id) for user_id in users_id_list]
usergroup.created_by = self.request.user.username or 'Admin' user_group.created_by = self.request.user.username or 'Admin'
usergroup.users.add(*tuple(users)) user_group.users.add(*tuple(users))
usergroup.save() user_group.save()
return super(UserGroupAddView, self).form_valid(form) return super(UserGroupCreateView, self).form_valid(form)
class UserGroupUpdateView(UpdateView): class UserGroupUpdateView(UpdateView):

View File

@ -3,7 +3,7 @@
## 语言框架 ## 语言框架
1. Python 2.7 由于ansible目前不支持python3 1. Python 2.7 由于ansible目前不支持python3
2. Django 1.10 (最新版本) 2. Django 1.10 (最新版本)
3. Terminal Websocket使用go实现 3. Terminal Websocket使用go实现 (未来)
## Django规范 ## Django规范
@ -32,7 +32,8 @@ Python方面大致的风格我们采用pocoo的[Style Guidance](http://www.po
#### 最大行长度 #### 最大行长度
按PEP8规范Python一般限制最大79个字符, 如果有必要最多84个字符 按PEP8规范Python一般限制最大79个字符, 但是Django的命名,url等通常比较长,
而且21世纪都是宽屏了,所以我们限制最大120字符
**补充说明HTML代码不受此规范约束。** **补充说明HTML代码不受此规范约束。**

0
logs/.gitkeep Normal file
View File