master
gaosiao 1 year ago
parent e0ff6eba08
commit 16fad0ad7d

8
.gitignore vendored

@ -0,0 +1,8 @@
/.vscode/
/dbs/
/doc/
/eggs/
/logs/
pythonÃüÁî.txt
/webview/node_modules/
/webview/.vscode/

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 hsp
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,2 +1,78 @@
# weibo-analysis-system-master
## weibo-analysis-system
`毕业设计`:微博用户情感分析系统
> (2020/02/02)更新近日有不少童鞋来问我这个项目跑不起的问题当时水平有点不够写的确实有点乱这里简单说明一下项目下下来直接跑起的方法。前提先搞好python环境和vue环境,保证你有一个账户密码连上数据库mysql。
1、pip install requirements.txt 安装python包
2、修改mysql数据库的账户密码weibosystem/ssettings里面
3、创建数据库 python manage.py makemigrations python manage.py migrate
4、创建后台xadmin账户python manage.py createsuperuser
5、登录后台http://localhost:8000/xadmin/SpiderAPI/target/ 在爬虫API里面的爬虫设置输入一个用户uid + cookie然后即可开始在首页localhost:8000数据爬虫id爬虫
### 1、系统介绍2019.5.4毕设已完成):
> extra_appsxadmin后台管理系统
> scrapydserverScrapy爬虫
> srcdjango app里面写接口
> webview前端Vue代码
> weibosystemdjango wsgi/url等配置
#### 1、系统技术架构介绍
> 前端使用vue-cli + vue + vuex + axios
> 后端使用python + django + xadmin + request + scrapy + scrapyd + snownlp模型已训练好但并不是特别准确
#### 2、系统功能介绍
> ① 输入微博oid爬取个人微博信息情感分析处理后并展示oid获取方式进入个人微博首页如 https://weibo.com/u/1797112632 ,其中`1797112632`就是oid。有些用户自定义了域名右击查看网页源代码搜索`['oid']`即可找到oid。下图是本系统爬取个人信息界面
![个人微博爬虫前端主界面](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/1.png?raw=true)
![个人微博爬虫前端信息展示](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/3.png?raw=true)
> ② 输入单条微博id爬取个人微博信息获取单条微博id的方式打开微博客户端随便找到一条微博进入微博正文点击右上角三个点然后可以看到分享给微信好友QQ好友等在下面一栏有收藏等往右边拖找到复制链接复制并粘贴出来。如 https://m.weibo.cn/1769965211/4366947749433348 ,其中`4366947749433348`就是单条微博id。情感分析处理后并展示。本系统展示单条微博例子如下
![单条微博爬虫前端信息展示](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/4.png?raw=true)
> ③ 输入微博id或者多个微博id和Cookie启动持续爬虫。前提先运行Scrapyd服务。这个功能使用Scrpay爬虫然后把数据存到Django的Model中。
![多用户爬虫启动](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/7.png?raw=true)
> ④ 独立出来的文本情感分析API输入任意一段中文返回情感分析值词频关键词。
![独立爬虫API](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/8.png?raw=true)
> ⑤ 数据库已爬虫的用户其中持续爬虫模块点击进去就是③中的多用户爬虫默认设置了组别是1如需修改进入xadmin后台修改即可上面的点击个人账号点击单条微博也是进入信息展示界面。点击组别进入的多用户爬虫界面如下图
![已爬虫用户](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/2.png?raw=true)
![多用户爬虫展示](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/5.png?raw=true)
> ⑥ xadmin后台管理系统
![xadmin后台管理系统](https://github.com/Superbsco/weibo-analysis-system/blob/master/pic/6.png?raw=true)
### 2、系统启动注意事项
[参考技术文档](https://github.com/Superbsco/weibo-analysis-system/blob/master/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%E8%AF%B4%E6%98%8E.md)
按照技术文档按照完了之后workon进入虚拟环境
#### 1、数据库自动生成使用如下命令
```python
python manage.py makemigrations
python manage.py migrate
```
#### 2、初始化Cookies
爬虫之前一定要先进入xadmin后台使用数据库自动生成后xadmin的登录账号密码就没了参考这里初始化账号https://blog.csdn.net/a_little_snail/article/details/76984933
然后重设Cookie获取新浪微博Cookie可参考 https://blog.csdn.net/A_xiao_mili/article/details/77947802 这里。

@ -0,0 +1,14 @@
[main]
host = https://www.transifex.com
[xadmin-core.django]
file_filter = locale/<lang>/LC_MESSAGES/django.po
source_file = locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO
[xadmin-core.djangojs]
file_filter = locale/<lang>/LC_MESSAGES/djangojs.po
source_file = locale/en/LC_MESSAGES/djangojs.po
source_lang = en
type = PO

@ -0,0 +1,70 @@
VERSION = (0,6,0)
from xadmin.sites import AdminSite, site
class Settings(object):
pass
def autodiscover():
"""
Auto-discover INSTALLED_APPS admin.py modules and fail silently when
not present. This forces an import on them to register any admin bits they
may want.
"""
from importlib import import_module
from django.conf import settings
from django.utils.module_loading import module_has_submodule
from django.apps import apps
setattr(settings, 'CRISPY_TEMPLATE_PACK', 'bootstrap3')
setattr(settings, 'CRISPY_CLASS_CONVERTERS', {
"textinput": "textinput textInput form-control",
"fileinput": "fileinput fileUpload form-control",
"passwordinput": "textinput textInput form-control",
})
from xadmin.views import register_builtin_views
register_builtin_views(site)
# load xadmin settings from XADMIN_CONF module
try:
xadmin_conf = getattr(settings, 'XADMIN_CONF', 'xadmin_conf.py')
conf_mod = import_module(xadmin_conf)
except Exception:
conf_mod = None
if conf_mod:
for key in dir(conf_mod):
setting = getattr(conf_mod, key)
try:
if issubclass(setting, Settings):
site.register_settings(setting.__name__, setting)
except Exception:
pass
from xadmin.plugins import register_builtin_plugins
register_builtin_plugins(site)
for app_config in apps.get_app_configs():
mod = import_module(app_config.name)
# Attempt to import the app's admin module.
try:
before_import_registry = site.copy_registry()
import_module('%s.adminx' % app_config.name)
except:
# Reset the model registry to the state before the last import as
# this import will have to reoccur on the next request and this
# could raise NotRegistered and AlreadyRegistered exceptions
# (see #8245).
site.restore_registry(before_import_registry)
# Decide whether to bubble up this error. If the app just
# doesn't have an admin module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'adminx'):
raise
default_app_config = 'xadmin.apps.XAdminConfig'

@ -0,0 +1,32 @@
from __future__ import absolute_import
import xadmin
from .models import UserSettings, Log
from xadmin.layout import *
from django.utils.translation import ugettext_lazy as _, ugettext
class UserSettingsAdmin(object):
model_icon = 'fa fa-cog'
hidden_menu = True
xadmin.site.register(UserSettings, UserSettingsAdmin)
class LogAdmin(object):
def link(self, instance):
if instance.content_type and instance.object_id and instance.action_flag != 'delete':
admin_url = self.get_admin_url('%s_%s_change' % (instance.content_type.app_label, instance.content_type.model),
instance.object_id)
return "<a href='%s'>%s</a>" % (admin_url, _('Admin Object'))
else:
return ''
link.short_description = ""
link.allow_tags = True
link.is_column = False
list_display = ('action_time', 'user', 'ip_addr', '__str__', 'link')
list_filter = ['user', 'action_time']
search_fields = ['ip_addr', 'message']
model_icon = 'fa fa-cog'
xadmin.site.register(Log, LogAdmin)

@ -0,0 +1,15 @@
from django.apps import AppConfig
from django.core import checks
from django.utils.translation import ugettext_lazy as _
import xadmin
class XAdminConfig(AppConfig):
"""Simple AppConfig which does not do automatic discovery."""
name = 'xadmin'
verbose_name = _("Administration")
def ready(self):
self.module.autodiscover()
setattr(xadmin,'site',xadmin.site)

@ -0,0 +1,573 @@
from __future__ import absolute_import
from django.db import models
from django.core.exceptions import ImproperlyConfigured
from django.utils.encoding import smart_text
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.template.loader import get_template
from django.template.context import Context
from django.utils import six
from django.utils.safestring import mark_safe
from django.utils.html import escape, format_html
from django.utils.text import Truncator
from django.core.cache import cache, caches
from xadmin.views.list import EMPTY_CHANGELIST_VALUE
from xadmin.util import is_related_field, is_related_field2
import datetime
FILTER_PREFIX = '_p_'
SEARCH_VAR = '_q_'
from .util import (get_model_from_relation,
reverse_field_path, get_limit_choices_to_from_path, prepare_lookup_value)
class BaseFilter(object):
title = None
template = 'xadmin/filters/list.html'
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
pass
def __init__(self, request, params, model, admin_view):
self.used_params = {}
self.request = request
self.params = params
self.model = model
self.admin_view = admin_view
if self.title is None:
raise ImproperlyConfigured(
"The filter '%s' does not specify "
"a 'title'." % self.__class__.__name__)
def query_string(self, new_params=None, remove=None):
return self.admin_view.get_query_string(new_params, remove)
def form_params(self):
arr = map(lambda k: FILTER_PREFIX + k, self.used_params.keys())
if six.PY3:
arr = list(arr)
return self.admin_view.get_form_params(remove=arr)
def has_output(self):
"""
Returns True if some choices would be output for this filter.
"""
raise NotImplementedError
@property
def is_used(self):
return len(self.used_params) > 0
def do_filte(self, queryset):
"""
Returns the filtered queryset.
"""
raise NotImplementedError
def get_context(self):
return {'title': self.title, 'spec': self, 'form_params': self.form_params()}
def __str__(self):
tpl = get_template(self.template)
return mark_safe(tpl.render(context=self.get_context()))
class FieldFilterManager(object):
_field_list_filters = []
_take_priority_index = 0
def register(self, list_filter_class, take_priority=False):
if take_priority:
# This is to allow overriding the default filters for certain types
# of fields with some custom filters. The first found in the list
# is used in priority.
self._field_list_filters.insert(
self._take_priority_index, list_filter_class)
self._take_priority_index += 1
else:
self._field_list_filters.append(list_filter_class)
return list_filter_class
def create(self, field, request, params, model, admin_view, field_path):
for list_filter_class in self._field_list_filters:
if not list_filter_class.test(field, request, params, model, admin_view, field_path):
continue
return list_filter_class(field, request, params,
model, admin_view, field_path=field_path)
manager = FieldFilterManager()
class FieldFilter(BaseFilter):
lookup_formats = {}
def __init__(self, field, request, params, model, admin_view, field_path):
self.field = field
self.field_path = field_path
self.title = getattr(field, 'verbose_name', field_path)
self.context_params = {}
super(FieldFilter, self).__init__(request, params, model, admin_view)
for name, format in self.lookup_formats.items():
p = format % field_path
self.context_params["%s_name" % name] = FILTER_PREFIX + p
if p in params:
value = prepare_lookup_value(p, params.pop(p))
self.used_params[p] = value
self.context_params["%s_val" % name] = value
else:
self.context_params["%s_val" % name] = ''
arr = map(
lambda kv: setattr(self, 'lookup_' + kv[0], kv[1]),
self.context_params.items()
)
if six.PY3:
list(arr)
def get_context(self):
context = super(FieldFilter, self).get_context()
context.update(self.context_params)
obj = map(lambda k: FILTER_PREFIX + k, self.used_params.keys())
if six.PY3:
obj = list(obj)
context['remove_url'] = self.query_string({}, obj)
return context
def has_output(self):
return True
def do_filte(self, queryset):
return queryset.filter(**self.used_params)
class ListFieldFilter(FieldFilter):
template = 'xadmin/filters/list.html'
def get_context(self):
context = super(ListFieldFilter, self).get_context()
context['choices'] = list(self.choices())
return context
@manager.register
class BooleanFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact', 'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, (models.BooleanField, models.NullBooleanField))
def choices(self):
for lookup, title in (
('', _('All')),
('1', _('Yes')),
('0', _('No')),
):
yield {
'selected': (
self.lookup_exact_val == lookup
and not self.lookup_isnull_val
),
'query_string': self.query_string(
{self.lookup_exact_name: lookup},
[self.lookup_isnull_name],
),
'display': title,
}
if isinstance(self.field, models.NullBooleanField):
yield {
'selected': self.lookup_isnull_val == 'True',
'query_string': self.query_string(
{self.lookup_isnull_name: 'True'},
[self.lookup_exact_name],
),
'display': _('Unknown'),
}
@manager.register
class ChoicesFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return bool(field.choices)
def choices(self):
yield {
'selected': self.lookup_exact_val is '',
'query_string': self.query_string({}, [self.lookup_exact_name]),
'display': _('All')
}
for lookup, title in self.field.flatchoices:
yield {
'selected': smart_text(lookup) == self.lookup_exact_val,
'query_string': self.query_string({self.lookup_exact_name: lookup}),
'display': title,
}
@manager.register
class TextFieldListFilter(FieldFilter):
template = 'xadmin/filters/char.html'
lookup_formats = {'in': '%s__in', 'search': '%s__contains'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return (
isinstance(field, models.CharField)
and field.max_length > 20
or isinstance(field, models.TextField)
)
@manager.register
class NumberFieldListFilter(FieldFilter):
template = 'xadmin/filters/number.html'
lookup_formats = {'equal': '%s__exact', 'lt': '%s__lt', 'gt': '%s__gt',
'ne': '%s__ne', 'lte': '%s__lte', 'gte': '%s__gte',
}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, (models.DecimalField, models.FloatField, models.IntegerField))
def do_filte(self, queryset):
params = self.used_params.copy()
ne_key = '%s__ne' % self.field_path
if ne_key in params:
queryset = queryset.exclude(
**{self.field_path: params.pop(ne_key)})
return queryset.filter(**params)
@manager.register
class DateFieldListFilter(ListFieldFilter):
template = 'xadmin/filters/date.html'
lookup_formats = {'since': '%s__gte', 'until': '%s__lt',
'year': '%s__year', 'month': '%s__month', 'day': '%s__day',
'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, models.DateField)
def __init__(self, field, request, params, model, admin_view, field_path):
self.field_generic = '%s__' % field_path
self.date_params = dict([(FILTER_PREFIX + k, v) for k, v in params.items()
if k.startswith(self.field_generic)])
super(DateFieldListFilter, self).__init__(
field, request, params, model, admin_view, field_path)
now = timezone.now()
# When time zone support is enabled, convert "now" to the user's time
# zone so Django's definition of "Today" matches what the user expects.
if now.tzinfo is not None:
current_tz = timezone.get_current_timezone()
now = now.astimezone(current_tz)
if hasattr(current_tz, 'normalize'):
# available for pytz time zones
now = current_tz.normalize(now)
if isinstance(field, models.DateTimeField):
today = now.replace(hour=0, minute=0, second=0, microsecond=0)
else: # field is a models.DateField
today = now.date()
tomorrow = today + datetime.timedelta(days=1)
self.links = (
(_('Any date'), {}),
(_('Has date'), {
self.lookup_isnull_name: False
}),
(_('Has no date'), {
self.lookup_isnull_name: 'True'
}),
(_('Today'), {
self.lookup_since_name: str(today),
self.lookup_until_name: str(tomorrow),
}),
(_('Past 7 days'), {
self.lookup_since_name: str(today - datetime.timedelta(days=7)),
self.lookup_until_name: str(tomorrow),
}),
(_('This month'), {
self.lookup_since_name: str(today.replace(day=1)),
self.lookup_until_name: str(tomorrow),
}),
(_('This year'), {
self.lookup_since_name: str(today.replace(month=1, day=1)),
self.lookup_until_name: str(tomorrow),
}),
)
def get_context(self):
context = super(DateFieldListFilter, self).get_context()
context['choice_selected'] = bool(self.lookup_year_val) or bool(self.lookup_month_val) \
or bool(self.lookup_day_val)
return context
def choices(self):
for title, param_dict in self.links:
yield {
'selected': self.date_params == param_dict,
'query_string': self.query_string(
param_dict, [FILTER_PREFIX + self.field_generic]),
'display': title,
}
@manager.register
class RelatedFieldSearchFilter(FieldFilter):
template = 'xadmin/filters/fk_search.html'
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
if not is_related_field2(field):
return False
related_modeladmin = admin_view.admin_site._registry.get(
get_model_from_relation(field))
return related_modeladmin and getattr(related_modeladmin, 'relfield_style', None) in ('fk-ajax', 'fk-select')
def __init__(self, field, request, params, model, model_admin, field_path):
other_model = get_model_from_relation(field)
if hasattr(field, 'remote_field'):
rel_name = field.remote_field.get_related_field().name
else:
rel_name = other_model._meta.pk.name
self.lookup_formats = {'in': '%%s__%s__in' % rel_name, 'exact': '%%s__%s__exact' % rel_name}
super(RelatedFieldSearchFilter, self).__init__(
field, request, params, model, model_admin, field_path)
related_modeladmin = self.admin_view.admin_site._registry.get(other_model)
self.relfield_style = related_modeladmin.relfield_style
if hasattr(field, 'verbose_name'):
self.lookup_title = field.verbose_name
else:
self.lookup_title = other_model._meta.verbose_name
self.title = self.lookup_title
self.search_url = model_admin.get_admin_url('%s_%s_changelist' % (
other_model._meta.app_label, other_model._meta.model_name))
self.label = self.label_for_value(other_model, rel_name, self.lookup_exact_val) if self.lookup_exact_val else ""
self.choices = '?'
if field.remote_field.limit_choices_to:
for i in list(field.remote_field.limit_choices_to):
self.choices += "&_p_%s=%s" % (i, field.remote_field.limit_choices_to[i])
self.choices = format_html(self.choices)
def label_for_value(self, other_model, rel_name, value):
try:
obj = other_model._default_manager.get(**{rel_name: value})
return '%s' % escape(Truncator(obj).words(14, truncate='...'))
except (ValueError, other_model.DoesNotExist):
return ""
def get_context(self):
context = super(RelatedFieldSearchFilter, self).get_context()
context['search_url'] = self.search_url
context['label'] = self.label
context['choices'] = self.choices
context['relfield_style'] = self.relfield_style
return context
@manager.register
class RelatedFieldListFilter(ListFieldFilter):
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return is_related_field2(field)
def __init__(self, field, request, params, model, model_admin, field_path):
other_model = get_model_from_relation(field)
if hasattr(field, 'remote_field'):
rel_name = field.remote_field.get_related_field().name
else:
rel_name = other_model._meta.pk.name
self.lookup_formats = {'in': '%%s__%s__in' % rel_name, 'exact': '%%s__%s__exact' %
rel_name, 'isnull': '%s__isnull'}
self.lookup_choices = field.get_choices(include_blank=False)
super(RelatedFieldListFilter, self).__init__(
field, request, params, model, model_admin, field_path)
if hasattr(field, 'verbose_name'):
self.lookup_title = field.verbose_name
else:
self.lookup_title = other_model._meta.verbose_name
self.title = self.lookup_title
def has_output(self):
if (is_related_field(self.field)
and self.field.field.null or hasattr(self.field, 'remote_field')
and self.field.null):
extra = 1
else:
extra = 0
return len(self.lookup_choices) + extra > 1
def expected_parameters(self):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
def choices(self):
yield {
'selected': self.lookup_exact_val == '' and not self.lookup_isnull_val,
'query_string': self.query_string({},
[self.lookup_exact_name, self.lookup_isnull_name]),
'display': _('All'),
}
for pk_val, val in self.lookup_choices:
yield {
'selected': self.lookup_exact_val == smart_text(pk_val),
'query_string': self.query_string({
self.lookup_exact_name: pk_val,
}, [self.lookup_isnull_name]),
'display': val,
}
if (is_related_field(self.field)
and self.field.field.null or hasattr(self.field, 'remote_field')
and self.field.null):
yield {
'selected': bool(self.lookup_isnull_val),
'query_string': self.query_string({
self.lookup_isnull_name: 'True',
}, [self.lookup_exact_name]),
'display': EMPTY_CHANGELIST_VALUE,
}
@manager.register
class MultiSelectFieldListFilter(ListFieldFilter):
""" Delegates the filter to the default filter and ors the results of each
Lists the distinct values of each field as a checkbox
Uses the default spec for each
"""
template = 'xadmin/filters/checklist.html'
lookup_formats = {'in': '%s__in'}
cache_config = {'enabled': False, 'key': 'quickfilter_%s', 'timeout': 3600, 'cache': 'default'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return True
def get_cached_choices(self):
if not self.cache_config['enabled']:
return None
c = caches(self.cache_config['cache'])
return c.get(self.cache_config['key'] % self.field_path)
def set_cached_choices(self, choices):
if not self.cache_config['enabled']:
return
c = caches(self.cache_config['cache'])
return c.set(self.cache_config['key'] % self.field_path, choices)
def __init__(self, field, request, params, model, model_admin, field_path, field_order_by=None, field_limit=None, sort_key=None, cache_config=None):
super(MultiSelectFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
# Check for it in the cachce
if cache_config is not None and type(cache_config) == dict:
self.cache_config.update(cache_config)
if self.cache_config['enabled']:
self.field_path = field_path
choices = self.get_cached_choices()
if choices:
self.lookup_choices = choices
return
# Else rebuild it
queryset = self.admin_view.queryset().exclude(**{"%s__isnull" % field_path: True}).values_list(field_path, flat=True).distinct()
#queryset = self.admin_view.queryset().distinct(field_path).exclude(**{"%s__isnull"%field_path:True})
if field_order_by is not None:
# Do a subquery to order the distinct set
queryset = self.admin_view.queryset().filter(id__in=queryset).order_by(field_order_by)
if field_limit is not None and type(field_limit) == int and queryset.count() > field_limit:
queryset = queryset[:field_limit]
self.lookup_choices = [str(it) for it in queryset.values_list(field_path, flat=True) if str(it).strip() != ""]
if sort_key is not None:
self.lookup_choices = sorted(self.lookup_choices, key=sort_key)
if self.cache_config['enabled']:
self.set_cached_choices(self.lookup_choices)
def choices(self):
self.lookup_in_val = (type(self.lookup_in_val) in (tuple, list)) and self.lookup_in_val or list(self.lookup_in_val)
yield {
'selected': len(self.lookup_in_val) == 0,
'query_string': self.query_string({}, [self.lookup_in_name]),
'display': _('All'),
}
for val in self.lookup_choices:
yield {
'selected': smart_text(val) in self.lookup_in_val,
'query_string': self.query_string({self.lookup_in_name: ",".join([val] + self.lookup_in_val), }),
'remove_query_string': self.query_string({self.lookup_in_name: ",".join([v for v in self.lookup_in_val if v != val]), }),
'display': val,
}
@manager.register
class AllValuesFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact', 'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return True
def __init__(self, field, request, params, model, admin_view, field_path):
parent_model, reverse_path = reverse_field_path(model, field_path)
queryset = parent_model._default_manager.all()
# optional feature: limit choices base on existing relationships
# queryset = queryset.complex_filter(
# {'%s__isnull' % reverse_path: False})
limit_choices_to = get_limit_choices_to_from_path(model, field_path)
queryset = queryset.filter(limit_choices_to)
self.lookup_choices = (queryset
.distinct()
.order_by(field.name)
.values_list(field.name, flat=True))
super(AllValuesFieldListFilter, self).__init__(
field, request, params, model, admin_view, field_path)
def choices(self):
yield {
'selected': (self.lookup_exact_val is '' and self.lookup_isnull_val is ''),
'query_string': self.query_string({}, [self.lookup_exact_name, self.lookup_isnull_name]),
'display': _('All'),
}
include_none = False
for val in self.lookup_choices:
if val is None:
include_none = True
continue
val = smart_text(val)
yield {
'selected': self.lookup_exact_val == val,
'query_string': self.query_string({self.lookup_exact_name: val},
[self.lookup_isnull_name]),
'display': val,
}
if include_none:
yield {
'selected': bool(self.lookup_isnull_val),
'query_string': self.query_string({self.lookup_isnull_name: 'True'},
[self.lookup_exact_name]),
'display': EMPTY_CHANGELIST_VALUE,
}

@ -0,0 +1,47 @@
from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import ugettext_lazy, ugettext as _
from django.contrib.auth import get_user_model
ERROR_MESSAGE = ugettext_lazy("Please enter the correct username and password "
"for a staff account. Note that both fields are case-sensitive.")
class AdminAuthenticationForm(AuthenticationForm):
"""
A custom authentication form used in the admin app.
"""
this_is_the_login_form = forms.BooleanField(
widget=forms.HiddenInput, initial=1,
error_messages={'required': ugettext_lazy("Please log in again, because your session has expired.")})
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
message = ERROR_MESSAGE
if username and password:
self.user_cache = authenticate(
username=username, password=password)
if self.user_cache is None:
if u'@' in username:
User = get_user_model()
# Mistakenly entered e-mail address instead of username? Look it up.
try:
user = User.objects.get(email=username)
except (User.DoesNotExist, User.MultipleObjectsReturned):
# Nothing to do here, moving along.
pass
else:
if user.check_password(password):
message = _("Your e-mail address is not your username."
" Try '%s' instead.") % user.username
raise forms.ValidationError(message)
elif not self.user_cache.is_active or not self.user_cache.is_staff:
raise forms.ValidationError(message)
return self.cleaned_data

@ -0,0 +1,113 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import *
from crispy_forms.bootstrap import *
from crispy_forms.utils import render_field, flatatt, TEMPLATE_PACK
from crispy_forms import layout
from crispy_forms import bootstrap
import math
class Fieldset(layout.Fieldset):
template = "xadmin/layout/fieldset.html"
def __init__(self, legend, *fields, **kwargs):
self.description = kwargs.pop('description', None)
self.collapsed = kwargs.pop('collapsed', None)
super(Fieldset, self).__init__(legend, *fields, **kwargs)
class Row(layout.Div):
def __init__(self, *fields, **kwargs):
css_class = 'form-inline form-group'
new_fields = [self.convert_field(f, len(fields)) for f in fields]
super(Row, self).__init__(css_class=css_class, *new_fields, **kwargs)
def convert_field(self, f, counts):
col_class = "col-sm-%d" % int(math.ceil(12 / counts))
if not (isinstance(f, Field) or issubclass(f.__class__, Field)):
f = layout.Field(f)
if f.wrapper_class:
f.wrapper_class += " %s" % col_class
else:
f.wrapper_class = col_class
return f
class Col(layout.Column):
def __init__(self, id, *fields, **kwargs):
css_class = ['column', 'form-column', id, 'col col-sm-%d' %
kwargs.get('span', 6)]
if kwargs.get('horizontal'):
css_class.append('form-horizontal')
super(Col, self).__init__(css_class=' '.join(css_class), *
fields, **kwargs)
class Main(layout.Column):
css_class = "column form-column main col col-sm-9 form-horizontal"
class Side(layout.Column):
css_class = "column form-column sidebar col col-sm-3"
class Container(layout.Div):
css_class = "form-container row clearfix"
# Override bootstrap3
class InputGroup(layout.Field):
template = "xadmin/layout/input_group.html"
def __init__(self, field, *args, **kwargs):
self.field = field
self.inputs = list(args)
if '@@' not in args:
self.inputs.append('@@')
self.input_size = None
css_class = kwargs.get('css_class', '')
if 'input-lg' in css_class:
self.input_size = 'input-lg'
if 'input-sm' in css_class:
self.input_size = 'input-sm'
super(InputGroup, self).__init__(field, **kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
classes = form.fields[self.field].widget.attrs.get('class', '')
extra_context = {
'inputs': self.inputs,
'input_size': self.input_size,
'classes': classes.replace('form-control', '')
}
if hasattr(self, 'wrapper_class'):
extra_context['wrapper_class'] = self.wrapper_class
return render_field(
self.field, form, form_style, context, template=self.template,
attrs=self.attrs, template_pack=template_pack, extra_context=extra_context, **kwargs)
class PrependedText(InputGroup):
def __init__(self, field, text, **kwargs):
super(PrependedText, self).__init__(field, text, '@@', **kwargs)
class AppendedText(InputGroup):
def __init__(self, field, text, **kwargs):
super(AppendedText, self).__init__(field, '@@', text, **kwargs)
class PrependedAppendedText(InputGroup):
def __init__(self, field, prepended_text=None, appended_text=None, *args, **kwargs):
super(PrependedAppendedText, self).__init__(
field, prepended_text, '@@', appended_text, **kwargs)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,72 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Azd325 <tim.kleinschmidt@gmail.com>, 2013
# Azd325 <tim.kleinschmidt@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: Azd325 <tim.kleinschmidt@gmail.com>\n"
"Language-Team: German (Germany) (http://www.transifex.com/projects/p/xadmin/language/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s von %(cnt)s markiert"
msgstr[1] "%(sel)s von %(cnt)s markiert"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Neues Element"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "So Mo Di Mi Do Fr Sa So"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "So Mo Di Mi Do Fr Sa So"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Januar Februar März April Mai Juni Juli August September Oktober November Dezember"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Heute"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "vorm nachm"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "vorm nachm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,69 @@
# 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: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,76 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# byroncorrales <byroncorrales@gmail.com>, 2013
# byroncorrales <byroncorrales@gmail.com>, 2013
# sacrac <crocha09.09@gmail.com>, 2013
# netoxico <me@netoxico.com>, 2013
# netoxico <me@netoxico.com>, 2013
# sacrac <crocha09.09@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sacrac <crocha09.09@gmail.com>\n"
"Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/xadmin/language/es_MX/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es_MX\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s de %(cnt)s seleccionado."
msgstr[1] "%(sel)s de %(cnt)s seleccionado "
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Nuevo elemento"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado Domingo"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Dom Lun Mar Mié Jue Vie Sáb Dom"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Do Lu Ma Mi Ju Vi Sá Do"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Hoy"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# unaizalakain <unai@gisa-elkartea.org>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: unaizalakain <unai@gisa-elkartea.org>\n"
"Language-Team: Basque (http://www.transifex.com/projects/p/xadmin/language/eu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(cnt)stik %(sel)s aukeratua"
msgstr[1] "%(cnt)stik %(sel)s aukeratuak"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Elementu Berria"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Igandea Astelehena Asteartea Asteazkena Osteguna Ostirala Larunbata Igandea"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Iga Atl Atr Atz Otg Otr Lar Iga"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Ig At Ar Az Og Or La Ig"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Urtarrila Otsaila Martxoa Apirila Maiatza Ekaina Uztaila Abuztua Iraila Urria Azaroa Abendua"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Urt Ots Mar Api Mai Eka Uzt Abu Ira Urr Aza Abe"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Gaur"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,69 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/xadmin/language/id_ID/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id_ID\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,69 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Japanese (http://www.transifex.com/projects/p/xadmin/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Lithuanian (http://www.transifex.com/projects/p/xadmin/language/lt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lt\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,70 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/xadmin/language/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nl_NL\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,83 @@
# 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.
#
msgid ""
msgstr ""
"Project-Id-Version: django-xadmin\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-08-12 21:07+0200\n"
"PO-Revision-Date: 2014-08-12 21:23+0100\n"
"Last-Translator: Michał Szpadzik <mszpadzik@gmail.com>\n"
"Language-Team: Polish translators <mszpadzik@gmail.com>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.5.4\n"
#: static/xadmin/js/xadmin.plugin.actions.js:11
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s z %(cnt)s wybranych"
msgstr[1] "%(sel)s z %(cnt)s wybranych"
msgstr[2] "%(sel)s z %(cnt)s wybranych"
#: static/xadmin/js/xadmin.plugin.quick-form.js:172
msgid "Close"
msgstr "Zamknij"
#: static/xadmin/js/xadmin.plugin.quick-form.js:173
msgid "Add"
msgstr "Dodaj"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Nowy obiekt"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "niedziela poniedziałek wtorek środa czwartek piątek sobota niedziela"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "niedz. pon. wt. śr. czw. pt. sob. niedz."
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "niedz. pn. wt. śr. czw. pt. sob. niedz."
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
"styczeń luty marzec kwiecień maj czerwiec lipiec sierpień wrzesień "
"październik "
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "sty. lut. marz. kwie. maj czerw. lip. sier. wrze. paź. list. grudz."
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Dzisiaj"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# korndorfer <codigo.aberto@dorfer.com.br>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: korndorfer <codigo.aberto@dorfer.com.br>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/xadmin/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s de %(cnt)s selecionado"
msgstr[1] "%(sel)s de %(cnt)s selecionados"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Novo Item"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Domingo Segunda Terça Quarta Quinta Sexta Sábado Domingo"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Dom Seg Ter Qua Qui Sex Sáb Dom"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Do Sg Te Qa Qi Sx Sa Do"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Hoje"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/xadmin/language/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

File diff suppressed because it is too large Load Diff

@ -0,0 +1,87 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# sshwsfc <sshwsfc@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-22 16:02+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/xadmin/language/zh_CN/)\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.page.dashboard.js:14
#: static/xadmin/js/xadmin.plugin.details.js:24
#: static/xadmin/js/xadmin.plugin.quick-form.js:172
msgid "Close"
msgstr "关闭"
#: static/xadmin/js/xadmin.page.dashboard.js:15
msgid "Save changes"
msgstr "保存修改"
#: static/xadmin/js/xadmin.plugin.actions.js:11
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "选中了 %(cnt)s 个中的 %(sel)s 个"
msgstr[1] "选中了 %(cnt)s 个中的 %(sel)s 个"
#: static/xadmin/js/xadmin.plugin.details.js:25
msgid "Edit"
msgstr "编辑"
#: static/xadmin/js/xadmin.plugin.quick-form.js:173
msgid "Add"
msgstr "添加"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "新项目"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "星期日 星期一 星期二 星期三 星期四 星期五 星期六"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "日 一 二 三 四 五 六"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "日 一 二 三 四 五 六"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid "January February March April May June July August September October November December"
msgstr "一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一 十二"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "今天"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "上午 下午"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "上午 下午"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.2 on 2016-03-20 13:46
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL)
]
operations = [
migrations.CreateModel(
name='Bookmark',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=128, verbose_name='Title')),
('url_name', models.CharField(max_length=64, verbose_name='Url Name')),
('query', models.CharField(blank=True, max_length=1000, verbose_name='Query String')),
('is_share', models.BooleanField(default=False, verbose_name='Is Shared')),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'Bookmark',
'verbose_name_plural': 'Bookmarks',
},
),
migrations.CreateModel(
name='UserSettings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.CharField(max_length=256, verbose_name='Settings Key')),
('value', models.TextField(verbose_name='Settings Content')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'User Setting',
'verbose_name_plural': 'User Settings',
},
),
migrations.CreateModel(
name='UserWidget',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('page_id', models.CharField(max_length=256, verbose_name='Page')),
('widget_type', models.CharField(max_length=50, verbose_name='Widget Type')),
('value', models.TextField(verbose_name='Widget Params')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'User Widget',
'verbose_name_plural': 'User Widgets',
},
),
]

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-15 05:50
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('xadmin', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Log',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('action_time', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='action time')),
('ip_addr', models.GenericIPAddressField(blank=True, null=True, verbose_name='action ip')),
('object_id', models.TextField(blank=True, null=True, verbose_name='object id')),
('object_repr', models.CharField(max_length=200, verbose_name='object repr')),
('action_flag', models.PositiveSmallIntegerField(verbose_name='action flag')),
('message', models.TextField(blank=True, verbose_name='change message')),
('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.ContentType', verbose_name='content type')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'ordering': ('-action_time',),
'verbose_name': 'log entry',
'verbose_name_plural': 'log entries',
},
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-15 06:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('xadmin', '0002_log'),
]
operations = [
migrations.AlterField(
model_name='log',
name='action_flag',
field=models.CharField(max_length=32, verbose_name='action flag'),
),
]

@ -0,0 +1,190 @@
import json
import django
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _, ugettext
from django.urls.base import reverse
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models.base import ModelBase
from django.utils.encoding import python_2_unicode_compatible, smart_text
from django.db.models.signals import post_migrate
from django.contrib.auth.models import Permission
import datetime
import decimal
from xadmin.util import quote
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
def add_view_permissions(sender, **kwargs):
"""
This syncdb hooks takes care of adding a view permission too all our
content types.
"""
# for each of our content types
for content_type in ContentType.objects.all():
# build our permission slug
codename = "view_%s" % content_type.model
# if it doesn't exist..
if not Permission.objects.filter(content_type=content_type, codename=codename):
# add it
Permission.objects.create(content_type=content_type,
codename=codename,
name="Can view %s" % content_type.name)
# print "Added view permission for %s" % content_type.name
# check for all our view permissions after a syncdb
post_migrate.connect(add_view_permissions)
@python_2_unicode_compatible
class Bookmark(models.Model):
title = models.CharField(_(u'Title'), max_length=128)
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"), blank=True, null=True)
url_name = models.CharField(_(u'Url Name'), max_length=64)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
query = models.CharField(_(u'Query String'), max_length=1000, blank=True)
is_share = models.BooleanField(_(u'Is Shared'), default=False)
@property
def url(self):
base_url = reverse(self.url_name)
if self.query:
base_url = base_url + '?' + self.query
return base_url
def __str__(self):
return self.title
class Meta:
verbose_name = _(u'Bookmark')
verbose_name_plural = _('Bookmarks')
class JSONEncoder(DjangoJSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d')
elif isinstance(o, decimal.Decimal):
return str(o)
elif isinstance(o, ModelBase):
return '%s.%s' % (o._meta.app_label, o._meta.model_name)
else:
try:
return super(JSONEncoder, self).default(o)
except Exception:
return smart_text(o)
@python_2_unicode_compatible
class UserSettings(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
key = models.CharField(_('Settings Key'), max_length=256)
value = models.TextField(_('Settings Content'))
def json_value(self):
return json.loads(self.value)
def set_json(self, obj):
self.value = json.dumps(obj, cls=JSONEncoder, ensure_ascii=False)
def __str__(self):
return "%s %s" % (self.user, self.key)
class Meta:
verbose_name = _(u'User Setting')
verbose_name_plural = _('User Settings')
@python_2_unicode_compatible
class UserWidget(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
page_id = models.CharField(_(u"Page"), max_length=256)
widget_type = models.CharField(_(u"Widget Type"), max_length=50)
value = models.TextField(_(u"Widget Params"))
def get_value(self):
value = json.loads(self.value)
value['id'] = self.id
value['type'] = self.widget_type
return value
def set_value(self, obj):
self.value = json.dumps(obj, cls=JSONEncoder, ensure_ascii=False)
def save(self, *args, **kwargs):
created = self.pk is None
super(UserWidget, self).save(*args, **kwargs)
if created:
try:
portal_pos = UserSettings.objects.get(
user=self.user, key="dashboard:%s:pos" % self.page_id)
portal_pos.value = "%s,%s" % (self.pk, portal_pos.value) if portal_pos.value else self.pk
portal_pos.save()
except Exception:
pass
def __str__(self):
return "%s %s widget" % (self.user, self.widget_type)
class Meta:
verbose_name = _(u'User Widget')
verbose_name_plural = _('User Widgets')
@python_2_unicode_compatible
class Log(models.Model):
action_time = models.DateTimeField(
_('action time'),
default=timezone.now,
editable=False,
)
user = models.ForeignKey(
AUTH_USER_MODEL,
models.CASCADE,
verbose_name=_('user'),
)
ip_addr = models.GenericIPAddressField(_('action ip'), blank=True, null=True)
content_type = models.ForeignKey(
ContentType,
models.SET_NULL,
verbose_name=_('content type'),
blank=True, null=True,
)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.CharField(_('action flag'), max_length=32)
message = models.TextField(_('change message'), blank=True)
class Meta:
verbose_name = _('log entry')
verbose_name_plural = _('log entries')
ordering = ('-action_time',)
def __repr__(self):
return smart_text(self.action_time)
def __str__(self):
if self.action_flag == 'create':
return ugettext('Added "%(object)s".') % {'object': self.object_repr}
elif self.action_flag == 'change':
return ugettext('Changed "%(object)s" - %(changes)s') % {
'object': self.object_repr,
'changes': self.message,
}
elif self.action_flag == 'delete' and self.object_repr:
return ugettext('Deleted "%(object)s."') % {'object': self.object_repr}
return self.message
def get_edited_object(self):
"Returns the edited object represented by this log entry"
return self.content_type.get_object_for_this_type(pk=self.object_id)

@ -0,0 +1,41 @@
PLUGINS = (
'actions',
'filters',
'bookmark',
'export',
'layout',
'refresh',
'details',
'editable',
'relate',
'chart',
'ajax',
'relfield',
'inline',
'topnav',
'portal',
'quickform',
'wizard',
'images',
'auth',
'multiselect',
'themes',
'aggregation',
# 'mobile',
'passwords',
'sitemenu',
'language',
'quickfilter',
'sortablelist',
'importexport'
)
def register_builtin_plugins(site):
from importlib import import_module
from django.conf import settings
exclude_plugins = getattr(settings, 'XADMIN_EXCLUDE_PLUGINS', [])
[import_module('xadmin.plugins.%s' % plugin) for plugin in PLUGINS if plugin not in exclude_plugins]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save