Repository: the5fire/django_selfblog Branch: master Commit: 3933e0a32c67 Files: 114 Total size: 824.6 KB Directory structure: gitextract_gv_0y55d/ ├── .gitignore ├── conf/ │ ├── nginx.conf │ ├── supervisord.conf │ └── the5fire.conf ├── deploy-blog-simple.yml ├── fabfile/ │ └── __init__.py ├── readme.rst ├── requirements.txt └── selfblog/ ├── __init__.py ├── blog/ │ ├── __init__.py │ ├── adminx.py │ ├── management/ │ │ ├── __init__.py │ │ └── commands/ │ │ ├── __init__.py │ │ ├── format_old.py │ │ ├── import_old.py │ │ └── replace_net.py │ ├── middleware.py │ ├── models.py │ ├── templates/ │ │ ├── 404.html │ │ ├── 500.html │ │ ├── base.html │ │ ├── detail.html │ │ ├── includes/ │ │ │ ├── footer.html │ │ │ ├── share.html │ │ │ └── sidebar.html │ │ ├── index.html │ │ ├── page.html │ │ ├── pingback.html │ │ └── sitemap.xml │ ├── templatetags/ │ │ ├── __init__.py │ │ └── substring.py │ ├── tests.py │ └── views.py ├── dump-auth.json ├── dump-blog.json ├── feeds.py ├── init_database.sh ├── manage.py ├── run.sh ├── selfblog/ │ ├── __init__.py │ ├── adminx.py │ ├── settings/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── develop.py │ │ └── product.py │ ├── urls.py │ └── wsgi.py ├── sitemap.py ├── static/ │ ├── admin/ │ │ ├── blog/ │ │ │ └── change_form.html │ │ ├── css/ │ │ │ ├── base.css │ │ │ ├── changelists.css │ │ │ ├── dashboard.css │ │ │ ├── forms.css │ │ │ ├── ie.css │ │ │ ├── jquery-ui-grappelli-extensions.css │ │ │ ├── login.css │ │ │ ├── rtl.css │ │ │ └── widgets.css │ │ ├── jquery/ │ │ │ ├── i18n/ │ │ │ │ ├── ui.datepicker-de.js │ │ │ │ └── ui.datepicker-fr.js │ │ │ ├── jquery.form.js │ │ │ └── ui/ │ │ │ └── css/ │ │ │ ├── custom-theme/ │ │ │ │ ├── jquery-ui-1.8.15.custom.css │ │ │ │ └── jquery-ui-1.8.custom.css │ │ │ └── ui-lightness/ │ │ │ └── jquery-ui-1.8.custom.css │ │ └── js/ │ │ ├── LICENSE-JQUERY.txt │ │ ├── SelectBox.js │ │ ├── SelectFilter2.js │ │ ├── actions.js │ │ ├── admin/ │ │ │ ├── DateTimeShortcuts.js │ │ │ ├── RelatedObjectLookups.js │ │ │ └── ordering.js │ │ ├── calendar.js │ │ ├── collapse.js │ │ ├── compress.py │ │ ├── core.js │ │ ├── dateparse.js │ │ ├── getElementsBySelector.js │ │ ├── grappelli/ │ │ │ ├── grappelli.js │ │ │ ├── jquery.grp_autocomplete_fk.js │ │ │ ├── jquery.grp_autocomplete_generic.js │ │ │ ├── jquery.grp_autocomplete_m2m.js │ │ │ ├── jquery.grp_collapsible.js │ │ │ ├── jquery.grp_collapsible_group.js │ │ │ ├── jquery.grp_inline.js │ │ │ ├── jquery.grp_related_fk.js │ │ │ ├── jquery.grp_related_generic.js │ │ │ ├── jquery.grp_related_m2m.js │ │ │ └── jquery.grp_timepicker.js │ │ ├── inlines.js │ │ ├── jquery.init.js │ │ ├── jquery.js │ │ ├── prepopulate.js │ │ ├── timeparse.js │ │ └── urlify.js │ ├── blog/ │ │ ├── css/ │ │ │ ├── code.css │ │ │ ├── codehilite.css │ │ │ └── style.css │ │ └── js/ │ │ └── prettify.js │ └── bootstrap/ │ ├── css/ │ │ ├── bootstrap-responsive.css │ │ ├── bootstrap.css │ │ ├── docs.css │ │ └── prettify.css │ └── js/ │ ├── bootstrap-dropdown.js │ └── bootstrap.js ├── utils/ │ ├── __init__.py │ ├── cache.py │ ├── markup.py │ └── profiler.py └── weixin/ ├── __init__.py ├── adminx.py ├── models.py ├── tests.py ├── urls.py └── views.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.pyc .idea .scrapy run build atlassian-ide-plugin.xml .project .pydevproject .env *.log *.sqlite3 .ropeproject/ ================================================ FILE: conf/nginx.conf ================================================ #user www-data; worker_processes 1; pid logs/nginx.pid; error_log logs/error.log info; events { use epoll; worker_connections 1024; multi_accept on; } http { include mime.types; default_type application/octet-stream; log_format info '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log info; keepalive_timeout 60; tcp_nodelay on; gzip on; include extra/the5fire.conf; } ================================================ FILE: conf/supervisord.conf ================================================ [unix_http_server] file=/home/the5fire/tmp/supervisor.sock ; (the path to the socket file) ;chmod=0700 ; socket file mode (default 0700) ;chown=root:root ; socket file uid:gid owner ;username={{ username }} ; (default is no username (open server)) ;password={{ password }} ; (default is no password (open server)) [supervisord] logfile=/home/the5fire/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/home/the5fire/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) ;umask=022 ; (process file creation umask;default 022) ;user=chrism ; (default is current user, required if root) ;identifier=supervisor ; (supervisord identifier, default is 'supervisor') ;directory=/tmp ; (default is not to cd during start) ;nocleanup=true ; (don't clean up tempfiles at start;default false) ;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP) ;environment=KEY=value ; (key value pairs to add to environment) ;strip_ansi=false ; (strip ansi escape codes in logs; def. false) [supervisorctl] serverurl=unix:///home/the5fire/tmp/supervisor.sock ; use a unix:// URL for a unix socket ;username={{ username }} ; should be same as http_username if set ;password={{ password }} ; should be same as http_password if set ;prompt=mysupervisor ; cmd line prompt (default "supervisor") history_file=/home/the5fire/.sc_history ; use readline history if available ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be ; added by defining them in separate rpcinterface: sections [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [program:selfblog] command=/home/the5fire/bin/gunicorn selfblog.wsgi:application --bind 127.0.0.1:2116%(process_num)1d --workers 2 directory=/home/the5fire/selfblog process_name=%(program_name)s_%(process_num)d umask=022 startsecs=0 stopwaitsecs=0 redirect_stderr=true stdout_logfile=/home/the5fire/tmp/supervisord_stdout_%(process_num)02d.log numprocs=1 numprocs_start=0 ================================================ FILE: conf/the5fire.conf ================================================ upstream the5fire{ server 127.0.0.1:11115; server 127.0.0.1:11116; } server { listen 8080; server_name the5fire.com www.the5fire.com; charset utf-8; location /static/ { alias /home/the5fire/selfblog/static/; } location / { proxy_pass http://the5fire; proxy_intercept_errors on; proxy_redirect off; proxy_connect_timeout 60; proxy_set_header Host $host; } } ================================================ FILE: deploy-blog-simple.yml ================================================ --- - hosts: local # hosts中指定 remote_user: the5fire # 如果和当前用户一样,则无需指定 tasks: - name: check out django_blog git: dest=~/demos/django_selfblog repo=https://github.com/the5fire/django_selfblog update=yes - name: make virtualenv shell: 'virtualenv ~/demos' - name: install requirements pip: requirements=~/demos/django_selfblog/requirements.txt virtualenv=~/demos - name: init database shell: . ./bin/activate && cd django_selfblog/selfblog && ./init_database.sh chdir=~/demos - name: run manage.py shell: . ./bin/activate && cd django_selfblog/selfblog && ./run.sh chdir=~/demos ================================================ FILE: fabfile/__init__.py ================================================ #coding:utf-8 from fabric.api import run, roles, cd, parallel, task from fabric.state import env www_path = '/home/the5fire/selfblog' supervisord_bin_path = '/home/the5fire/bin' supervisord_conf_file = '/home/the5fire/conf/supervisord.conf' env.roledefs = { 'server': ['root@xxx.xxx.xxx'] } @task @roles('server') def host_type(): run('uname -s') @task @parallel(22) @roles('server') def top(): run("top -b | head -n 1") def git_co(path, branch='master'): with(cd(path)): run('git reset --hard && git pull -f && git checkout %s' % branch) def supervisord_restart(path, conf_path): with(cd(path)): run('./supervisorctl -c %s restart all' % (conf_path, )) @task @roles('server') def re_deploy(branch='django15'): git_co(www_path, branch=branch) supervisord_restart(supervisord_bin_path, supervisord_conf_file) @task @roles('server') def re_mem(): run("ps aux|grep 'the5fire/memcached' | grep -v 'grep' | awk '{print $2}' | xargs kill -9") run("memcached -d -m memory -s /home/the5fire/memcached.sock -P /home/the5fire/memcached.pid") ================================================ FILE: readme.rst ================================================ ======================= the5fire的技术博客源码 ======================= 博客地址: http://the5fire.com 微信号: .. image:: http://the5fireblog.b0.upaiyun.com/staticfile/getqrcode.jpeg 概述 ------------------------------- 本博客系统基于Django1.5.1开发而成,通过gunicorn运行于Webfaction上,Python版本为2.7.4, 更多描述看这里: `说说我这个博客的架构 `_ ,其中Django的版本后来被升级为1.6.1的。 功能 ----------------------------- 1. 文章、分类和页面的增删改查 2. 通过rst格式或者html格式书写文章正文 3. 侧边栏的组件化调整(目前比较弱) 4. 集成多说的评论 5. RSS和rpc 6. 其他的自己看把,博客上能看到的功能代码都在这里了 2014-05-02添加 -------------------------------- 微信自动回复接口 2014-05-31 ------------------------------- 后台修改为xadmin(0.5v) 2016-07-02 ------------------------------- * Post增加is_md字段,增加对markdown格式的支持 * 拆分settings.py文件为develop.py,product.py让配置更清晰 * 通过DJANGOSELFBLOG_PROFILE来加载对应的配置develop/product * 修复创建Post时不填英文标题导致的文章无法访问的bug 哪些技术 ------------------------------ 主要是对Django的Class-Base View的一个实践。另外也是项目开发、部署、维护的基本流程的演练。 技术都在架构里有说。 如何使用 ----------------------------- 安装virtualenv:: sudo pip install virtualenv 创建虚拟环境:: virtualenv www 把项目放到www目录,cd到目录中,执行:: cd www # 激活虚拟环境 source bin/activate # 安装依赖包 pip install -r requirements.txt 创建数据库或表:: # 针对sqlite3,mysql的话需要先创建数据库然后修改settings中的配置 # 在django_selfblog/selfblog目录下执行 python manage.py syncdb 运行:: # 直接运行 python manage.py runserver #或者用gunicorn gunicorn selfblog.wsgi:application 访问:: http://localhost:8000 部署注意:: 需要修改settings中关于debug模式的判断 需要修改数据库的设置 需要修改DOMAIN和admin邮箱的设置 ... 帮忙改善 ----------------------- 本来打算在完善一些代码,再发出来,怎奈有太多的东西要学习,不能立马开始完善。遂想不如拿出来让大家一起改进。 分享你的blog ---------------------- 我建了个ISSUE,方便用此源码的同学分享自己搭建的成果:https://github.com/the5fire/django_selfblog/issues/2 使用ansible一键部署 --------------------------- 写了一个ansible的脚本: `deploy-blog-simple.yml `_ 在配置好ansible之后,可以一句话完成部署操作:: $ ansible-play deploy-blog-simple.yml 这样执行完成之后,程序会在你配置好的服务器上自动的搭建虚拟环境,并安装依赖,启动blog程序,监听在8000端口,直接可以通过ip+端口进行访问: http://your-ip:8000 ,后台地址:http://your-ip:8000/xadmin 。 **用户名/密码** 均为 **the5fire** 不了解ansible的童鞋可以看下这里: `ansible中文指南 `_ 来个截图看看: .. image:: img/quick-glance.png 更新后xadmin的后台图: .. image:: img/xadmin-screen.png ================================================ FILE: requirements.txt ================================================ Django==1.6 -e git+https://github.com/duoshuo/duoshuo-python-sdk.git#egg=duoshuo-python-sdk django-pingback django-xmlrpc==0.1.4 gunicorn==18.0 BeautifulSoup==3.2.1 supervisor==3.0 Docutils==0.11 Pygments==1.6 MySQL-python python-memcached==1.53 django-debug-toolbar==0.10.2 django-xadmin==0.5.0 django-ipware markdown ================================================ FILE: selfblog/__init__.py ================================================ ================================================ FILE: selfblog/blog/__init__.py ================================================ ================================================ FILE: selfblog/blog/adminx.py ================================================ # coding:utf-8 import markdown import xadmin from django.core import urlresolvers from .models import Post from .models import Category from .models import Page from .models import Widget from utils.markup import restructuredtext class PostAdmin(object): search_fields = ('title', 'alias') fields = ('content', 'summary', 'title', 'alias', 'tags', 'status', 'category', 'is_top', 'is_old', 'pub_time') list_display = ('preview', 'title', 'category', 'is_top', 'pub_time') list_display_links = ('title', ) ordering = ('-pub_time', ) list_per_page = 15 save_on_top = True def preview(self, obj): url_edit = urlresolvers.reverse('xadmin:blog_post_change', args=(obj.id,)) return u''' 预览 编辑 ''' % (obj.alias, url_edit) preview.short_description = u'操作' preview.allow_tags = True def save_models(self): obj = self.new_obj obj.author = self.request.user if not obj.summary: obj.summary = obj.content if obj.is_md: obj.content_html = markdown.markdown(obj.content, extensions=['codehilite']) elif not obj.is_old: obj.content_html = restructuredtext(obj.content) else: obj.content_html = obj.content.replace('\r\n', '
') import re obj.content_html = re.sub(r"\[cc lang='\w+?'\]", '
', obj.content_html)
            obj.content_html = obj.content_html.replace('[/cc]', '
') obj.save() class CategoryAdmin(object): search_fields = ('name', 'alias') list_display = ('name', 'rank', 'is_nav', 'status', 'create_time') class PageAdmin(object): search_fields = ('name', 'alias') fields = ('title', 'alias', 'link', 'content', 'is_html', 'status', 'rank') list_display = ('title', 'link', 'rank', 'status', 'is_html') def save_models(self): obj = self.new_obj obj.author = self.request.user if obj.is_html: obj.content_html = obj.content else: obj.content_html = restructuredtext(obj.content) obj.save() class WidgetAdmin(object): search_fields = ('name', 'alias') fields = ('title', 'content', 'rank', 'hide') list_display = ('title', 'rank', 'hide') xadmin.site.register(Post, PostAdmin) xadmin.site.register(Category, CategoryAdmin) xadmin.site.register(Page, PageAdmin) xadmin.site.register(Widget, WidgetAdmin) ================================================ FILE: selfblog/blog/management/__init__.py ================================================ ================================================ FILE: selfblog/blog/management/commands/__init__.py ================================================ ================================================ FILE: selfblog/blog/management/commands/format_old.py ================================================ #coding:utf-8 from django.core.management.base import BaseCommand from blog.models import Post class Command(BaseCommand): args = 'no' help = 'import old post' def handle(self, *args, **options): format_all() def format_all(): posts = Post.objects.filter(is_old=True) for post in posts: print post.title #处理代码 post.content = post.content.replace("[cc lang=\'python\']", '
').replace("[/cc]", "
") #处理换行 post.content_html = post.content.replace('\n\n', '
').replace('\n', '
') post.save() ================================================ FILE: selfblog/blog/management/commands/import_old.py ================================================ #coding:utf-8 import re from datetime import datetime try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET from django.core.management.base import BaseCommand from django.contrib.auth.models import User from blog.models import Post, Category class Command(BaseCommand): args = 'no' help = 'import old post' def handle(self, *args, **options): parse_xml() def parse_xml(): et = ET.ElementTree(file='/home/the5fire/Downloads/the5fire.xml') root = et.getroot() user = User.objects.get(username='the5fire') count = 1 alias_re = re.compile(r'^[a-z|0-9|\-]+$') for channel in root.findall('channel'): for item in channel.findall('item'): title = item.find('title') post_name = item.find('{http://wordpress.org/export/1.2/}post_name') pubDate = item.find('pubDate') description = item.find('description') content = item.find('{http://purl.org/rss/1.0/modules/content/}encoded') categories = item.findall('category') tags = [] category = Category() for ca in categories: if ca.attrib['domain'] == 'post_tag': tags.append(ca.text) else: try: category = Category.objects.get(name=ca.text) except Category.DoesNotExist: category.name = ca.text if alias_re.match(ca.attrib['nicename']): category.alias = ca.attrib['nicename'] else: category.alias = category.name print category.alias category.save() try: Post.objects.get(title=title.text) print title.text, 'already exist' continue except Post.DoesNotExist: pass post = Post() post.title = title.text post.category = category if alias_re.match(post_name.text): post.alias = post_name.text else: post.alias = title.text print post.alias post.content = content.text post.content_html = content.text if not description.text: post.summary = content.text[:140] else: post.summary = description.text post.is_old = True post.tags = ','.join(tags) create_time = pubDate.text[:-6] tf = '%a, %d %b %Y %H:%M:%S' post.old_pub_time = datetime.strptime(create_time, tf) print post.old_pub_time post.author = user try: post.save() print count, post count += 1 except Exception, e: print e ================================================ FILE: selfblog/blog/management/commands/replace_net.py ================================================ #coding:utf-8 from django.core.management.base import BaseCommand from blog.models import Post class Command(BaseCommand): args = 'no' help = 'import old post' def handle(self, *args, **options): replace_all() def replace_all(): posts = Post.objects.filter(is_old=True) for post in posts: #print post.title #处理代码 index = post.content.find('the5fire.net') if index > 0: print post.title post.content = post.content.replace("www.the5fire.net", 'www.the5fire.com') post.content_html = post.content_html.replace("www.the5fire.net", 'www.the5fire.com') post.save() ================================================ FILE: selfblog/blog/middleware.py ================================================ #coding:utf-8 import time import logging from ipware.ip import get_real_ip from utils.cache import cache logger = logging.getLogger(__name__) class OnlineMiddleware(object): def process_request(self, request): self.start_time = time.time() def process_view(self, request, view_func, view_args, view_kwargs): """ 处理当前在线人数 """ http_user_agent = request.META.get('HTTP_USER_AGENT', []) if 'Spider' in http_user_agent or 'spider' in http_user_agent: return online_ips = cache.get("online_ips", []) if online_ips: online_ips = cache.get_many(online_ips).keys() ip = get_real_ip(request) cache.set(ip, 0, 5 * 60) if ip not in online_ips: online_ips.append(ip) cache.set("online_ips", online_ips) def process_response(self, request, response): cast_time = time.time() - self.start_time response.content = response.content.replace('', str(cast_time)[:5]) return response ================================================ FILE: selfblog/blog/models.py ================================================ # coding:utf-8 from datetime import datetime from django.contrib.auth.models import User from django.db import models from django.db.models import signals from django.dispatch import receiver from django.utils.functional import cached_property from django.conf import settings from utils.cache import cache_decorator STATUS = { 0: u'正常', 1: u'草稿', 2: u'删除', } class Category(models.Model): name = models.CharField(max_length=40, verbose_name=u'名称') alias = models.CharField(max_length=40, verbose_name=u'英文名') is_nav = models.BooleanField(default=False, verbose_name=u'是否在导航位置显示') parent = models.ForeignKey('self', default=None, blank=True, null=True, verbose_name=u'上级分类') desc = models.CharField(max_length=100, blank=True, verbose_name=u'描述', help_text=u'点击分类之后显示') rank = models.IntegerField(default=0, verbose_name=u'展示排序') status = models.IntegerField(default=0, choices=STATUS.items(), verbose_name=u'状态') create_time = models.DateTimeField(u'创建时间', auto_now_add=True) update_time = models.DateTimeField(u'更新时间', auto_now=True) def __unicode__(self): if self.parent: return '%s:%s' % (self.parent, self.name) else: return '%s' % (self.name) @classmethod @cache_decorator(1*60) def available_list(cls): return cls.objects.filter(status=0) class Meta: ordering = ['rank', '-create_time'] verbose_name_plural = verbose_name = u"分类" app_label = u'博客' class Post(models.Model): author = models.ForeignKey(User, verbose_name=u'作者') category = models.ForeignKey(Category, verbose_name=u'分类') title = models.CharField(max_length=100, verbose_name=u'标题') alias = models.CharField(max_length=100, db_index=True, blank=True, null=True, verbose_name=u'英文标题', help_text=u'做伪静态url用') is_top = models.BooleanField(default=False, verbose_name=u'置顶') summary = models.TextField(verbose_name=u'摘要') content = models.TextField(verbose_name=u'文章正文rst/md格式') content_html = models.TextField(verbose_name=u'文章正文html') view_times = models.IntegerField(default=1) tags = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'标签', help_text=u'用英文逗号分割') status = models.IntegerField(default=0, choices=STATUS.items(), verbose_name=u'状态') is_md = models.BooleanField(default=False, verbose_name=u'是否为Markdown格式') is_old = models.BooleanField(default=False, verbose_name=u'是否为旧数据') pub_time = models.DateTimeField(default=datetime.now, verbose_name=u'发布时间') create_time = models.DateTimeField(u'创建时间', auto_now_add=True, editable=True) update_time = models.DateTimeField(u'更新时间', auto_now=True) def __unicode__(self): return self.title def tags_list(self): return [tag.strip() for tag in self.tags.split(',')] def get_absolute_url(self): return '%s/%s.html' % (settings.DOMAIN, self.alias) @cached_property def next_post(self): # 下一篇 return Post.objects.filter(id__gt=self.id, status=0).order_by('id').first() @cached_property def prev_post(self): # 前一篇 return Post.objects.filter(id__lt=self.id, status=0).first() @classmethod @cache_decorator(1*60) def get_recently_posts(cls, num): return cls.objects.values('title', 'alias')\ .filter(status=0).order_by('-create_time')[:num] @classmethod @cache_decorator(1*60) def get_hots_posts(cls, num): return cls.objects.values('title', 'alias')\ .filter(status=0).order_by('-view_times')[:num] @cache_decorator(3*60) def related_posts(self): related_posts = None try: related_posts = Post.objects.values('title', 'alias').\ filter(tags__icontains=self.tags_list()[0]).\ exclude(id=self.id)[:10] except IndexError: pass if not related_posts: related_posts = Post.objects.values('title', 'alias').\ filter(category=self.category).\ exclude(id=self.id)[:10] return related_posts class Meta: ordering = ['-is_top', '-pub_time', '-create_time'] verbose_name_plural = verbose_name = u"文章" app_label = u'博客' @receiver(signals.post_save, sender=Post) def check_or_update_post_alias(sender, instance=None, **kwargs): # 如果alias未设置则使用id if not instance.alias: instance.alias = instance.id instance.save() class Page(models.Model): author = models.ForeignKey(User, verbose_name=u'作者') title = models.CharField(max_length=100, verbose_name=u'标题') alias = models.CharField(max_length=100, blank=True, null=True, verbose_name=u'英文标题', help_text=u'做伪静态url用') content = models.TextField(verbose_name=u'page正文') content_html = models.TextField(verbose_name=u'page正文html') is_html = models.BooleanField(default=False, verbose_name=u'html代码') link = models.CharField(max_length=200, blank=True, null=True, verbose_name=u'链接', help_text=u'该链接存在时其它内容无效') rank = models.IntegerField(default=1, verbose_name=u'排序', help_text=u'从右到左的顺序') status = models.IntegerField(default=0, choices=STATUS.items(), verbose_name=u'状态') create_time = models.DateTimeField(u'创建时间', auto_now_add=True) update_time = models.DateTimeField(u'更新时间', auto_now=True) def __unicode__(self): return self.title class Meta: ordering = ['-rank', '-create_time'] verbose_name_plural = verbose_name = u"页面" app_label = u'博客' class Widget(models.Model): title = models.CharField(max_length=100, verbose_name=u'标题') content = models.TextField(verbose_name=u'widget内容', help_text=u'html代码不会被转义') hide = models.BooleanField(default=False, verbose_name=u'隐藏') rank = models.IntegerField(default=0, verbose_name=u'展示排序') create_time = models.DateTimeField(u'创建时间', auto_now_add=True) update_time = models.DateTimeField(u'更新时间', auto_now=True) def __unicode__(self): return self.title @classmethod @cache_decorator(1*60) def available_list(cls): return cls.objects.filter(hide=False) class Meta: ordering = ['rank', '-create_time'] verbose_name_plural = verbose_name = u"侧栏组件" app_label = u'博客' ================================================ FILE: selfblog/blog/templates/404.html ================================================ {% extends "base.html" %} {% block main %} 噢,没有你要找的东西吗,到右边搜搜看!
{% endblock %} ================================================ FILE: selfblog/blog/templates/500.html ================================================ {% extends "base.html" %} {% block main %} 哦,程序又抽了 {% endblock %} ================================================ FILE: selfblog/blog/templates/base.html ================================================ {% block title %}{% endblock %}the5fire的技术博客 {% block extend_style %}{% endblock %}

the5fire的技术博客

关注python、vim、linux、web开发和互联网--life is short, we need python.
{% block main %}{% endblock %}
其他分类:
{% include "includes/footer.html" %} {% block extend_js %}{% endblock %} ================================================ FILE: selfblog/blog/templates/detail.html ================================================ {% extends "base.html" %} {% load duoshuo_tags %} {% block title %}{{ post.title }} | {% endblock %} {% block desc %}{{ post.summary|truncatewords:140 }}{% endblock %} {% block keywords %}{{ post.tags }}{% endblock %} {% block extend_style %} {% if post.is_md %} {% else %} {% endif %} {% endblock %} {% block main %}

{% autoescape off %} {{ post.title }} {% endautoescape %}

{% if post %}
作者:{{ post.author }} | 分类:{{ post.category.name }} | 标签: {% for tag in post.tags_list %}   {% endfor %} | 阅读 {{ post.view_times }} 次 | 发布:{{ post.pub_time|date:"Y-m-d P" }} {% if user.is_authenticated %} edit {% endif %}
{% include 'includes/share.html' %}
{% autoescape off %} {{ post.content_html }} {% endautoescape %}
{% include 'includes/share.html' %}
相关文章
别人正在读
    {% for ip, post in lru_views %} {% if ip != cur_user_ip %}
  • {{ post.title }}
  • {% endif %} {% endfor %}
【上一篇】 {% if post.prev_post %} {{ post.prev_post.title }} {% else %} 没有了 {% endif %}
【下一篇】 {% if post.next_post %} {{ post.next_post.title }} {% else %} 没有了 {% endif %}
{% endif %} {% duoshuo_comments %} {% include "pingback.html" %}
{% endblock %} {% block extend_js %} {% endblock %} ================================================ FILE: selfblog/blog/templates/includes/footer.html ================================================

版权所有 © 2010-2016 }} the5fire.com

CC BY-NC-SA 3.0

Powered by Django.

Host on DigitalOcean $5/月.

当前{{ online_num }}人在线,表示毫无压力 {% if online_num > 50 %} 囧~ {% endif %} {% if online_num < 10 %} 汗~ {% endif %}

本页面加载耗时:s

网站地图

================================================ FILE: selfblog/blog/templates/includes/share.html ================================================ ================================================ FILE: selfblog/blog/templates/includes/sidebar.html ================================================
{% for widget in widgets %} {% if widget.content == 'recently_post'%}

{{ widget.title }}

    {% with r_posts=recently_posts %} {% if r_posts %} {% for post in r_posts %}
  • {{ post.title }}
  • {% endfor %} {% endif %} {% endwith %}
{% else %}{% if widget.content == 'hot_post' %}

{{ widget.title }}

    {% with h_posts=hot_posts %} {% if h_posts %} {% for post in h_posts %}
  • {{ post.title }}
  • {% endfor %} {% endif %} {% endwith %}
{% else %}

{{ widget.title }}

{% autoescape off %} {{ widget.content }} {% endautoescape %}
{% endif %}{% endif %} {% endfor %}
================================================ FILE: selfblog/blog/templates/index.html ================================================ {% extends "base.html" %} {% load substring %} {% if title %} {% block title %}{{ title }} {% endblock %} {% endif %} {% block main %} {% with post_list=posts.object_list %} {% if post_list %} {% for post in post_list %}

{% autoescape off %}{{ post.title }}{% endautoescape %}

作者:the5fire | 分类:{{ post.category.name }} | 标签: {% for tag in post.tags_list %}   {% endfor %} | 阅读 {{ post.view_times }} 次 | 发布:{{ post.pub_time|date:"Y-m-d P" }} {% if user.is_authenticated %} edit {% endif %}

{% autoescape on %} {{ post.summary|truncatewords:140 }} {% endautoescape %}

阅读全文
{% endfor %} {% endif %} {% endwith %}
{% endblock %} ================================================ FILE: selfblog/blog/templates/page.html ================================================ {% extends "base.html" %} {% load duoshuo_tags substring %} {% block title %}{{ page.title }} | {% endblock %} {% block desc %}{{ page.content|truncatewords:140 }}{% endblock %} {% block keywords %}{% for tag in page.tags_list %}{{ tag }},{% endfor %}{% endblock %} {% block main %}

{{ page.title }}

作者:{{ page.author }} | 发布:{{ page.create_time|date:"Y-m-d P" }}
{% autoescape off %} {{ page.content_html }} {% endautoescape %}
{% duoshuo_comments %}
{% endblock %} ================================================ FILE: selfblog/blog/templates/pingback.html ================================================ {% load i18n pingback_tags %} {% load pingback_tags %} {% get_pingback_list for object as pingbacks %} {% get_pingback_count for object as pingback_count %} {% if pingbacks %}

{{ pingback_count }} Pingbacks

{% for pingback in pingbacks %}
  • {{ pingback.date|date:"M d, Y" }}: {{ pingback.title }}
  • {% endfor %}
    {% endif %} ================================================ FILE: selfblog/blog/templates/sitemap.xml ================================================ {% spaceless %} {% for url in urlset %} {{ url.location }} {% if url.lastmod %}{{ url.lastmod|date:"Y-m-d\TH:i:s+08:00" }}{% endif %} {% if url.changefreq %}{{ url.changefreq }}{% endif %} {% if url.priority %}{{ url.priority }}{% endif %} {% endfor %} {% endspaceless %} ================================================ FILE: selfblog/blog/templatetags/__init__.py ================================================ ================================================ FILE: selfblog/blog/templatetags/substring.py ================================================ #coding:utf-8 from django import template register = template.Library() @register.filter(name='substring') def substring(value, length): if not value: return u'无摘要' if len(value) > length: return '%s...' % value[:length] return value[:length] @register.filter(name='sub') def sub(value, param): if not value: return value try: value = int(value) param = int(param) except TypeError: return value return value - param ================================================ FILE: selfblog/blog/tests.py ================================================ """ This file demonstrates writing tests using the unittest module. These will pass when you run "manage.py test". Replace this with more appropriate tests for your application. """ from django.test import TestCase class SimpleTest(TestCase): def test_basic_addition(self): """ Tests that 1 + 1 always equals 2. """ self.assertEqual(1 + 1, 2) ================================================ FILE: selfblog/blog/views.py ================================================ # coding:utf-8 import logging from django.db.models import Q from django.db.models import F from django.core.paginator import Paginator from django.views.generic import ListView, DetailView from django.shortcuts import render from ipware.ip import get_real_ip from django.conf import settings from .models import Post, Category, Page, Widget from utils.cache import LRUCacheDict, cache logger = logging.getLogger(__name__) class BaseMixin(object): def get_context_data(self, *args, **kwargs): if 'object' in kwargs or 'query' in kwargs: context = super(BaseMixin, self).get_context_data(**kwargs) else: context = {} try: context['categories'] = Category.available_list() context['widgets'] = Widget.available_list() context['recently_posts'] = Post.get_recently_posts(settings.RECENTLY_NUM) context['hot_posts'] = Post.get_hots_posts(settings.HOT_NUM) context['pages'] = Page.objects.filter(status=0) context['online_num'] = len(cache.get('online_ips', [])) except Exception as e: logger.exception(u'加载基本信息出错[%s]!', e) return context class IndexView(BaseMixin, ListView): query = None template_name = 'index.html' def get(self, request, *args, **kwargs): try: self.cur_page = int(request.GET.get('page', 1)) except TypeError: self.cur_page = 1 if self.cur_page < 1: self.cur_page = 1 return super(IndexView, self).get(request, *args, **kwargs) def get_context_data(self, **kwargs): paginator = Paginator(self.object_list, settings.PAGE_NUM) kwargs['posts'] = paginator.page(self.cur_page) kwargs['query'] = self.query return super(IndexView, self).get_context_data(**kwargs) def get_queryset(self): self.query = self.request.GET.get('s') if self.query: qset = ( Q(title__icontains=self.query) | Q(content__icontains=self.query) ) posts = Post.objects.defer('content', 'content_html')\ .filter(qset, status=0) for post in posts: post.title = post.title.replace(self.query, '%s' % self.query) post.summary = post.summary.replace(self.query, '%s' % self.query) else: posts = Post.objects.defer('content', 'content_html')\ .filter(status=0) return posts class CategoryListView(IndexView): def get_queryset(self): alias = self.kwargs.get('alias') try: self.category = Category.objects.get(alias=alias) except Category.DoesNotExist: return [] posts = self.category.post_set.defer('content', 'content_html').filter(status=0) return posts def get_context_data(self, **kwargs): if hasattr(self, 'category'): kwargs['title'] = self.category.name + ' | ' return super(CategoryListView, self).get_context_data(**kwargs) class TagsListView(IndexView): def get_queryset(self): self.tag = self.kwargs.get('tag') posts = Post.objects.defer('content', 'content_html')\ .filter(tags__icontains=self.tag, status=0) return posts def get_context_data(self, **kwargs): kwargs['title'] = self.tag + ' | ' return super(TagsListView, self).get_context_data(**kwargs) class PostDetailView(BaseMixin, DetailView): object = None template_name = 'detail.html' queryset = Post.objects.filter(status=0) slug_field = 'alias' def get(self, request, *args, **kwargs): ip = get_real_ip self.cur_user_ip = ip alias = self.kwargs.get('slug') alias = alias.replace(' ', '') try: self.object = self.queryset.get(alias=alias) except Post.DoesNotExist: referer = request.META.get('HTTP_REFERER') logger.error(u'ref[%s] [%s]访问不存在的文章:[%s]', referer, ip, alias) context = super(PostDetailView, self).get_context_data(**kwargs) return render(request, '404.html', context) visited_ips = cache.get(self.object.id, []) if ip not in visited_ips: Post.objects.filter(id=self.object.id).update(view_times=F('view_times')+1) visited_ips.append(ip) self.set_lru_read(ip, self.object) DAY = 24 * 60 # 一天 cache.set(self.object.id, visited_ips, DAY) context = self.get_context_data(object=self.object) return self.render_to_response(context) def set_lru_read(self, ip, post): # 保存别人正在读 lru_views = cache.get('lru_views') if not lru_views: lru_views = LRUCacheDict(max_size=10, expiration=settings.FIF_MIN) if post not in lru_views.values(): lru_views[ip] = post cache.set('lru_views', lru_views, settings.FIF_MIN) def get_context_data(self, **kwargs): context = super(PostDetailView, self).get_context_data(**kwargs) context['lru_views'] = cache.get('lru_views', {}).items() context['cur_user_ip'] = self.cur_user_ip context['related_posts'] = self.object.related_posts return context class PageDetailView(BaseMixin, DetailView): template_name = "page.html" queryset = Page.objects.filter(status=0) slug_field = 'alias' def get(self, request, *args, **kwargs): alias = self.kwargs.get('slug') try: self.object = self.queryset.get(alias=alias) context = self.get_context_data(object=self.object) except Page.DoesNotExist: logger.error(u'访问不存在的页面:[%s]' % alias) context = self.get_context_data(**kwargs) return render(request, '404.html', context) return self.render_to_response(context) ================================================ FILE: selfblog/dump-auth.json ================================================ [{"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "view_group", "name": "Can view group", "content_type": 2}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "view_permission", "name": "Can view permission", "content_type": 1}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "view_user", "name": "Can view user", "content_type": 3}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 4}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 4}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "view_contenttype", "name": "Can view content type", "content_type": 4}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 5}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 5}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 5}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "view_session", "name": "Can view session", "content_type": 5}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 6}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 6}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 6}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "view_site", "name": "Can view site", "content_type": 6}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 7}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 7}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 7}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "view_logentry", "name": "Can view log entry", "content_type": 7}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "add_pingback", "name": "Can add pingback", "content_type": 8}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "change_pingback", "name": "Can change pingback", "content_type": 8}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "delete_pingback", "name": "Can delete pingback", "content_type": 8}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "add_pingbackclient", "name": "Can add pingback client", "content_type": 9}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "change_pingbackclient", "name": "Can change pingback client", "content_type": 9}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "delete_pingbackclient", "name": "Can delete pingback client", "content_type": 9}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "add_directoryping", "name": "Can add directory ping", "content_type": 10}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "change_directoryping", "name": "Can change directory ping", "content_type": 10}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "delete_directoryping", "name": "Can delete directory ping", "content_type": 10}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "view_directoryping", "name": "Can view directory ping", "content_type": 10}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "view_pingback", "name": "Can view pingback", "content_type": 8}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "view_pingbackclient", "name": "Can view pingback client", "content_type": 9}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "add_category", "name": "Can add \u5206\u7c7b", "content_type": 11}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "change_category", "name": "Can change \u5206\u7c7b", "content_type": 11}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "delete_category", "name": "Can delete \u5206\u7c7b", "content_type": 11}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "add_post", "name": "Can add \u6587\u7ae0", "content_type": 12}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "change_post", "name": "Can change \u6587\u7ae0", "content_type": 12}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "delete_post", "name": "Can delete \u6587\u7ae0", "content_type": 12}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "add_page", "name": "Can add \u9875\u9762", "content_type": 13}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "change_page", "name": "Can change \u9875\u9762", "content_type": 13}}, {"pk": 49, "model": "auth.permission", "fields": {"codename": "delete_page", "name": "Can delete \u9875\u9762", "content_type": 13}}, {"pk": 50, "model": "auth.permission", "fields": {"codename": "add_widget", "name": "Can add \u4fa7\u680f\u7ec4\u4ef6", "content_type": 14}}, {"pk": 51, "model": "auth.permission", "fields": {"codename": "change_widget", "name": "Can change \u4fa7\u680f\u7ec4\u4ef6", "content_type": 14}}, {"pk": 52, "model": "auth.permission", "fields": {"codename": "delete_widget", "name": "Can delete \u4fa7\u680f\u7ec4\u4ef6", "content_type": 14}}, {"pk": 53, "model": "auth.permission", "fields": {"codename": "view_widget", "name": "Can view \u4fa7\u680f\u7ec4\u4ef6", "content_type": 14}}, {"pk": 54, "model": "auth.permission", "fields": {"codename": "view_category", "name": "Can view \u5206\u7c7b", "content_type": 11}}, {"pk": 55, "model": "auth.permission", "fields": {"codename": "view_post", "name": "Can view \u6587\u7ae0", "content_type": 12}}, {"pk": 56, "model": "auth.permission", "fields": {"codename": "view_page", "name": "Can view \u9875\u9762", "content_type": 13}}, {"pk": 57, "model": "auth.permission", "fields": {"codename": "add_menu", "name": "Can add \u83dc\u5355", "content_type": 15}}, {"pk": 58, "model": "auth.permission", "fields": {"codename": "change_menu", "name": "Can change \u83dc\u5355", "content_type": 15}}, {"pk": 59, "model": "auth.permission", "fields": {"codename": "delete_menu", "name": "Can delete \u83dc\u5355", "content_type": 15}}, {"pk": 60, "model": "auth.permission", "fields": {"codename": "add_responsemessage", "name": "Can add \u54cd\u5e94\u6d88\u606f", "content_type": 16}}, {"pk": 61, "model": "auth.permission", "fields": {"codename": "change_responsemessage", "name": "Can change \u54cd\u5e94\u6d88\u606f", "content_type": 16}}, {"pk": 62, "model": "auth.permission", "fields": {"codename": "delete_responsemessage", "name": "Can delete \u54cd\u5e94\u6d88\u606f", "content_type": 16}}, {"pk": 63, "model": "auth.permission", "fields": {"codename": "add_message", "name": "Can add \u7528\u6237\u6d88\u606f", "content_type": 17}}, {"pk": 64, "model": "auth.permission", "fields": {"codename": "change_message", "name": "Can change \u7528\u6237\u6d88\u606f", "content_type": 17}}, {"pk": 65, "model": "auth.permission", "fields": {"codename": "delete_message", "name": "Can delete \u7528\u6237\u6d88\u606f", "content_type": 17}}, {"pk": 66, "model": "auth.permission", "fields": {"codename": "add_event", "name": "Can add \u63a5\u53d7\u5230\u7684\u4e8b\u4ef6", "content_type": 18}}, {"pk": 67, "model": "auth.permission", "fields": {"codename": "change_event", "name": "Can change \u63a5\u53d7\u5230\u7684\u4e8b\u4ef6", "content_type": 18}}, {"pk": 68, "model": "auth.permission", "fields": {"codename": "delete_event", "name": "Can delete \u63a5\u53d7\u5230\u7684\u4e8b\u4ef6", "content_type": 18}}, {"pk": 69, "model": "auth.permission", "fields": {"codename": "view_responsemessage", "name": "Can view \u54cd\u5e94\u6d88\u606f", "content_type": 16}}, {"pk": 70, "model": "auth.permission", "fields": {"codename": "view_event", "name": "Can view \u63a5\u53d7\u5230\u7684\u4e8b\u4ef6", "content_type": 18}}, {"pk": 71, "model": "auth.permission", "fields": {"codename": "view_message", "name": "Can view \u7528\u6237\u6d88\u606f", "content_type": 17}}, {"pk": 72, "model": "auth.permission", "fields": {"codename": "view_menu", "name": "Can view \u83dc\u5355", "content_type": 15}}, {"pk": 73, "model": "auth.permission", "fields": {"codename": "add_bookmark", "name": "Can add Bookmark", "content_type": 19}}, {"pk": 74, "model": "auth.permission", "fields": {"codename": "change_bookmark", "name": "Can change Bookmark", "content_type": 19}}, {"pk": 75, "model": "auth.permission", "fields": {"codename": "delete_bookmark", "name": "Can delete Bookmark", "content_type": 19}}, {"pk": 76, "model": "auth.permission", "fields": {"codename": "add_usersettings", "name": "Can add User Setting", "content_type": 20}}, {"pk": 77, "model": "auth.permission", "fields": {"codename": "change_usersettings", "name": "Can change User Setting", "content_type": 20}}, {"pk": 78, "model": "auth.permission", "fields": {"codename": "delete_usersettings", "name": "Can delete User Setting", "content_type": 20}}, {"pk": 79, "model": "auth.permission", "fields": {"codename": "add_userwidget", "name": "Can add User Widget", "content_type": 21}}, {"pk": 80, "model": "auth.permission", "fields": {"codename": "change_userwidget", "name": "Can change User Widget", "content_type": 21}}, {"pk": 81, "model": "auth.permission", "fields": {"codename": "delete_userwidget", "name": "Can delete User Widget", "content_type": 21}}, {"pk": 1, "model": "auth.user", "fields": {"username": "the5fire", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2014-05-31T22:41:05.210", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$l7q6hwQuE3jV$Nt6Wt/rQqA8c5IidX/2ORPwqoUiTfMz/qykRRdvEWyI=", "email": "thefivefire@gmail.com", "date_joined": "2014-05-31T22:40:32.283"}}] ================================================ FILE: selfblog/dump-blog.json ================================================ [{"pk": 1, "model": "blog.category", "fields": {"is_nav": true, "status": 0, "update_time": "2014-05-31T23:09:20.497", "name": "\u535a\u5ba2", "parent": null, "rank": 0, "alias": "blog", "create_time": "2014-05-31T23:09:20.496", "desc": ""}}, {"pk": 1, "model": "blog.post", "fields": {"category": 1, "status": 0, "update_time": "2014-05-31T23:18:59.895", "pub_time": "2014-05-31T23:09:26", "is_old": false, "title": "\u7528reStructuredText\u6765\u5199\u535a\u5ba2(\u6d4b\u8bd5)", "author": 1, "view_times": 3, "summary": "\u5b83\u662f\u4e00\u4e2a\u7c7b\u4f3c\u4e8eMarkDown\u7684\u6807\u8bb0\u8bed\u8a00\uff0c\u5177\u4f53\u53ef\u53c2\u8003\u8fd9\u91cc\uff1ahttp://zh.wikipedia.org/wiki/ReStructuredText\r\n\r\n\u4e0b\u9762\u7528\u51e0\u4e2a\u4f8b\u5b50\u6765\u8bf4\u660e\u8fd9\u4e2a\u4e1c\u897f\u600e\u4e48\u7528\r\n", "content": "reStructuredText\u662f\u4ec0\u4e48\r\n######################\r\n\r\n\u5b83\u662f\u4e00\u4e2a\u7c7b\u4f3c\u4e8eMarkDown\u7684\u6807\u8bb0\u8bed\u8a00\uff0c\u5177\u4f53\u53ef\u53c2\u8003\u8fd9\u91cc\uff1ahttp://zh.wikipedia.org/wiki/ReStructuredText, \u624b\u518c\u5728\u8fd9\u91cc\uff1ahttp://sphinx-doc-zh.readthedocs.org/en/latest/rest.html\r\n\u4e0b\u9762\u7528\u51e0\u4e2a\u4f8b\u5b50\u6765\u8bf4\u660e\u8fd9\u4e2a\u4e1c\u897f\u600e\u4e48\u7528\r\n\r\n\u7ae0\u8282\r\n#########\r\n ::\r\n\r\n # \u6709\u4e0a\u6807\u7ebf, \u7528\u4ee5\u90e8\u5206\r\n * \u6709\u4e0a\u6807\u7ebf, \u7528\u4ee5\u7ae0\u8282\r\n = \u7528\u4ee5\u5c0f\u8282 \r\n - \u7528\u4ee5\u5b50\u8282 \r\n ^ \u7528\u4ee5\u5b50\u8282\u7684\u5b50\u8282 \r\n \" \u7528\u4ee5\u6bb5\u843d \r\n\r\n\u6bb5\u843d\r\n-----------------\r\n\r\n\u7528\u7a7a\u884c\u9694\u5f00\u5c31\u81ea\u52a8\u8bc6\u522b\u4e3a\u4e00\u4e2a\u6bb5\u843d\r\n\r\n\u94fe\u63a5\r\n----------------\r\n\u6548\u679c:\r\n\r\n `Link text `_ test \r\n\r\ncode:\r\n::\r\n\r\n `Link text `_ \r\n \u4e0a\u9762\u7684\u4ee3\u7801\u653e\u5230\u5185\u5bb9\u4e2d\u7684\u9700\u8981\u524d\u540e\u7a7a\u683c\u3002\r\n\r\n\r\n\r\n\r\n\u4ee3\u7801\r\n----------------------------\r\n\u6548\u679c\uff1a\r\n\r\n.. code:: python\r\n\r\n #coding:utf-8\r\n\r\n def hello():\r\n print 'hello the5fire'\r\n\r\ncode:\r\n::\r\n\r\n .. code:: python\r\n\r\n #coding:utf-8\r\n\r\n def hello():\r\n print 'hello the5fire'\r\n \r\n", "alias": "blog-with-restructuredtext", "is_top": false, "create_time": "2014-05-31T23:17:00.534", "content_html": "
    \n

    reStructuredText\u662f\u4ec0\u4e48

    \n

    \u5b83\u662f\u4e00\u4e2a\u7c7b\u4f3c\u4e8eMarkDown\u7684\u6807\u8bb0\u8bed\u8a00\uff0c\u5177\u4f53\u53ef\u53c2\u8003\u8fd9\u91cc\uff1ahttp://zh.wikipedia.org/wiki/ReStructuredText, \u624b\u518c\u5728\u8fd9\u91cc\uff1ahttp://sphinx-doc-zh.readthedocs.org/en/latest/rest.html\n\u4e0b\u9762\u7528\u51e0\u4e2a\u4f8b\u5b50\u6765\u8bf4\u660e\u8fd9\u4e2a\u4e1c\u897f\u600e\u4e48\u7528

    \n
    \n
    \n

    \u7ae0\u8282

    \n
    \n
    \n# \u6709\u4e0a\u6807\u7ebf, \u7528\u4ee5\u90e8\u5206\n* \u6709\u4e0a\u6807\u7ebf, \u7528\u4ee5\u7ae0\u8282\n= \u7528\u4ee5\u5c0f\u8282\n- \u7528\u4ee5\u5b50\u8282\n^ \u7528\u4ee5\u5b50\u8282\u7684\u5b50\u8282\n" \u7528\u4ee5\u6bb5\u843d\n
    \n
    \n
    \n

    \u6bb5\u843d

    \n

    \u7528\u7a7a\u884c\u9694\u5f00\u5c31\u81ea\u52a8\u8bc6\u522b\u4e3a\u4e00\u4e2a\u6bb5\u843d

    \n
    \n
    \n

    \u94fe\u63a5

    \n

    \u6548\u679c:

    \n
    \nLink text test
    \n

    code:

    \n
    \n`Link text <http://example.com/>`_\n \u4e0a\u9762\u7684\u4ee3\u7801\u653e\u5230\u5185\u5bb9\u4e2d\u7684\u9700\u8981\u524d\u540e\u7a7a\u683c\u3002\n
    \n
    \n
    \n

    \u4ee3\u7801<code>

    \n

    \u6548\u679c\uff1a

    \n
    \n#coding:utf-8\n\ndef hello():\n    print 'hello the5fire'\n
    \n

    code:

    \n
    \n.. code:: python\n\n    #coding:utf-8\n\n    def hello():\n        print 'hello the5fire'\n
    \n
    \n
    \n", "tags": "reStructuredText,blog"}}, {"pk": 1, "model": "blog.page", "fields": {"status": 0, "update_time": "2014-05-31T23:06:50.128", "author": 1, "is_html": true, "title": "\u5173\u4e8e", "rank": 1, "content": "

    \u5173\u4e8e\u535a\u4e3b

    \r\n

    life is short, we need python

    ", "alias": "about", "create_time": "2014-05-31T23:06:50.128", "link": "", "content_html": "

    \u5173\u4e8e\u535a\u4e3b

    \r\n

    life is short, we need python

    "}}, {"pk": 1, "model": "blog.widget", "fields": {"update_time": "2014-05-31T22:41:43.761", "hide": false, "title": "\u5173\u4e8e\u535a\u4e3b", "rank": 0, "content": "Python\u7a0b\u5e8f\u5458\u4e00\u679a", "create_time": "2014-05-31T22:41:43.761"}}, {"pk": 2, "model": "blog.widget", "fields": {"update_time": "2014-05-31T23:04:42.076", "hide": false, "title": "html\u5c55\u793a", "rank": 1, "content": "

    test

    \r\n

    \u6d4b\u8bd5\u6587\u672c

    \r\n\u4f5c\u8005\u535a\u5ba2", "create_time": "2014-05-31T23:04:42.076"}}] ================================================ FILE: selfblog/feeds.py ================================================ #coding:utf-8 from django.contrib.syndication.views import Feed from django.utils.feedgenerator import Rss201rev2Feed from blog.models import Post class ExtendedRSSFeed(Rss201rev2Feed): mime_type = 'application/xml' """ Create a type of RSS feed that has content:encoded elements. """ def root_attributes(self): attrs = super(ExtendedRSSFeed, self).root_attributes() attrs['xmlns:content'] = 'http://purl.org/rss/1.0/modules/content/' return attrs def add_item_elements(self, handler, item): super(ExtendedRSSFeed, self).add_item_elements(handler, item) handler.addQuickElement(u'content:encoded', item['content_encoded']) class LatestEntriesFeed(Feed): feed_type = ExtendedRSSFeed # Elements for the top-level, channel. title = u"the5fire的技术博客" link = "http://www.the5fire.com" author = 'the5fire' description = u"关注python、vim、linux、web开发和互联网--life is short, we need python." def items(self): return Post.objects.filter(status=0).order_by('-create_time')[:10] def item_extra_kwargs(self, item): return {'content_encoded': self.item_content_encoded(item)} # Elements for each item. def item_title(self, item): return item.title def item_description(self, item): return item.content_html def item_author_name(self, item): if (item.author.get_full_name()): return item.author.get_full_name() else: return item.author def item_pubdate(self, item): return item.create_time def item_content_encoded(self, item): return item.content_html ================================================ FILE: selfblog/init_database.sh ================================================ #!/bin/bash nohup python manage.py syncdb --noinput > /dev/null 2>&1 & sleep 5 nohup python manage.py loaddata dump-auth.json > /dev/null 2>&1 & nohup python manage.py loaddata dump-blog.json > /dev/null 2>&1 & ================================================ FILE: selfblog/manage.py ================================================ #!/usr/bin/env python import os import sys if __name__ == "__main__": PROFILE = os.environ.get('DJANGOSELFBLOG_PROFILE', 'develop') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "selfblog.settings.%s" % PROFILE) from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) ================================================ FILE: selfblog/run.sh ================================================ #!/bin/bash nohup python manage.py runserver 0.0.0.0:8000> /dev/null 2>&1 & ================================================ FILE: selfblog/selfblog/__init__.py ================================================ ================================================ FILE: selfblog/selfblog/adminx.py ================================================ # coding: utf-8 from __future__ import absolute_import, unicode_literals import xadmin from xadmin import views class GlobeSetting(object): site_title = 'the5fire博客后台' site_footer = 'power by the5fire' xadmin.site.register(views.CommAdminView, GlobeSetting) ================================================ FILE: selfblog/selfblog/settings/__init__.py ================================================ ================================================ FILE: selfblog/selfblog/settings/base.py ================================================ # coding:utf-8 import os from os import path ROOT_PATH = path.abspath(path.join(path.dirname('settings.py'), path.pardir)) ADMINS = ( ('the5fire', 'thefivefire@gmail.com'), ) ALLOWED_HOSTS = ['localhost', '.the5fire.com'] MANAGERS = ADMINS TIME_ZONE = 'Asia/Shanghai' LANGUAGE_CODE = 'zh-cn' SITE_ID = 1 USE_I18N = True USE_L10N = True MEDIA_ROOT = '' MEDIA_URL = '/media/' # STATIC_ROOT = '' STATIC_URL = '/static/' # Additional locations of static files STATICFILES_DIRS = ( path.join(ROOT_PATH, 'selfblog/static'), ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ) # Make this unique, and don't share it with anybody. SECRET_KEY = 'm_t&=vit))7cic$zfdl^7wfsc+$e1@_p=4@bmc54pp%25n#*%1' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', # 'django.template.loaders.eggs.Loader', ) MIDDLEWARE_CLASSES = ( 'django.middleware.gzip.GZipMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'pingback.middleware.PingbackMiddleware', 'blog.middleware.OnlineMiddleware', ) INTERNAL_IPS = ('127.0.0.1',) ROOT_URLCONF = 'selfblog.urls' WSGI_APPLICATION = 'selfblog.wsgi.application' TEMPLATE_DIRS = ( path.join(ROOT_PATH, 'blog/templates'), ) DIRECTORY_URLS = ( 'http://ping.blogs.yandex.ru/RPC2', 'http://rpc.technorati.com/rpc/ping', ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django_xmlrpc', 'xadmin', 'crispy_forms', 'pingback', 'duoshuo', 'blog', 'weixin', ) LOG_PATH = os.path.join(ROOT_PATH, '..', '..') LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'formatters': { 'simple': { 'format': '[%(levelname)s] %(module)s : %(message)s' }, 'verbose': { 'format': '[%(asctime)s] [%(levelname)s] %(module)s : %(message)s' } }, 'handlers': { 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'verbose' }, 'file_info': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'formatter': 'verbose', 'filename': os.path.join(LOG_PATH, 'info.log'), 'maxBytes': 1024 * 1024 * 100, 'backupCount': 10, 'mode': 'a', }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'filters': ['require_debug_false'] } }, 'loggers': { '': { 'handlers': ['file_info', 'console'], 'level': 'INFO', 'propagate': True, }, 'django': { 'handlers': ['file_info', 'console'], 'level': 'DEBUG', 'propagate': True, }, 'django.request': { 'handlers': ['mail_admins', 'console'], 'level': 'ERROR', 'propagate': True, }, } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'unique-snowflake', 'options': { 'MAX_ENTRIES': 1024, } }, 'memcache': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'unix:/home/the5fire/memcached.sock', 'options': { 'MAX_ENTRIES': 1024, } }, } # 配置文章开头使用rst格式无显示的问题 RESTRUCTUREDTEXT_FILTER_SETTINGS = { 'doctitle_xform': False, } PAGE_NUM = 10 RECENTLY_NUM = 15 HOT_NUM = 15 ONE_DAY = 24*60*60 FIF_MIN = 15 * 60 FIVE_MIN = 5 * 60 DUOSHUO_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxx' DUOSHUO_SHORT_NAME = 'xxxxxxxx' # 微信 WEIXIN_APPID = 0 WEIXIN_APPSECRET = '' ================================================ FILE: selfblog/selfblog/settings/develop.py ================================================ # coding:utf-8 from .base import * # noqa DEBUG = True TEMPLATE_DEBUG = DEBUG DOMAIN = 'http://localhost:8000' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'selfblog.sqlite3', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '', 'PORT': '', } } INSTALLED_APPS = INSTALLED_APPS + ('debug_toolbar', ) MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ('debug_toolbar.middleware.DebugToolbarMiddleware', ) ================================================ FILE: selfblog/selfblog/settings/product.py ================================================ # coding:utf-8 from .base import * # noqa DEBUG = True TEMPLATE_DEBUG = DEBUG DOMAIN = 'http://www.the5fire.com' # yourdomain DB_NAME = 'mydb' DB_USER = 'the5fire' DB_PWD = 'the5fire' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydb', 'USER': 'the5fire', 'PASSWORD': 'the5fire', 'HOST': '', 'PORT': '', } } ================================================ FILE: selfblog/selfblog/urls.py ================================================ # coding:utf-8 from django.conf.urls import patterns, include, url from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.sitemaps import views as sitemap_views from django.views.decorators.cache import cache_page import xadmin xadmin.autodiscover() from blog.views import (IndexView, CategoryListView, TagsListView, PostDetailView, PageDetailView) from feeds import LatestEntriesFeed from sitemap import PostSitemap import adminx # noqa 初始化adminx配置 urlpatterns = patterns( '', url(r'^$', IndexView.as_view(), name='home'), url(r'^feed|rss/$', LatestEntriesFeed()), url(r'^sitemap\.xml$', cache_page(60 * 60 * 12)(sitemap_views.sitemap), {'sitemaps': {'posts': PostSitemap}}), url(r'^category/(?P\w+)/', CategoryListView.as_view()), url(r'^tag/(?P[\w|\.|\-]+)/$', TagsListView.as_view()), url(r'^xadmin/', include(xadmin.site.urls), name='xadmin'), url(r'^xmlrpc/$', 'django_xmlrpc.views.handle_xmlrpc', {}, 'xmlrpc'), # 放到最后 url(r'^(?P[\w|\-|\d|\W]+?).html$', PostDetailView.as_view()), url(r'^(?P\w+)/$', PageDetailView.as_view()), ) urlpatterns += staticfiles_urlpatterns() ================================================ FILE: selfblog/selfblog/wsgi.py ================================================ import os PROFILE = os.environ.get('DJANGOSELFBLOG_PROFILE', 'develop') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "selfblog.settings.%s" % PROFILE) from django.core.wsgi import get_wsgi_application application = get_wsgi_application() # Apply WSGI middleware here. # from helloworld.wsgi import HelloWorldApplication # application = HelloWorldApplication(application) ================================================ FILE: selfblog/sitemap.py ================================================ #coding:utf-8 from django.contrib.sitemaps import Sitemap from blog.models import Post class PostSitemap(Sitemap): changefreq = "weekly" priority = 0.2 def items(self): return Post.objects.filter(status=0) def lastmod(self, obj): return obj.create_time def location(self, obj): return '/%s.html' % obj.alias ================================================ FILE: selfblog/static/admin/blog/change_form.html ================================================ {% extends "admin/change_form.html" %} {% block after_related_objects %} {% if original.pk %}
    {% if original.requested %} {% endif %} {% if original.submitted %} {% endif %} {% if original.submitted or original.assigned %} {% endif %} {% if original.accepted %} {% endif %} {% if original.cancelled %} {% endif %}
    {% endif %} {% endblock %} ================================================ FILE: selfblog/static/admin/css/base.css ================================================ /* DJANGO Admin styles */ body { margin: 0; padding: 0; font-size: 12px; font-family: "Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; color: #333; background: #fff; } /* LINKS */ a:link, a:visited { color: #5b80b2; text-decoration: none; } a:hover { color: #036; } a img { border: none; } a.section:link, a.section:visited { color: white; text-decoration: none; } /* GLOBAL DEFAULTS */ p, ol, ul, dl { margin: .2em 0 .8em 0; } p { padding: 0; line-height: 140%; } h1,h2,h3,h4,h5 { font-weight: bold; } h1 { font-size: 18px; color: #666; padding: 0 6px 0 0; margin: 0 0 .2em 0; } h2 { font-size: 16px; margin: 1em 0 .5em 0; } h2.subhead { font-weight: normal; margin-top: 0; } h3 { font-size: 14px; margin: .8em 0 .3em 0; color: #666; font-weight: bold; } h4 { font-size: 12px; margin: 1em 0 .8em 0; padding-bottom: 3px; } h5 { font-size: 10px; margin: 1.5em 0 .5em 0; color: #666; text-transform: uppercase; letter-spacing: 1px; } ul li { list-style-type: square; padding: 1px 0; } ul.plainlist { margin-left: 0 !important; } ul.plainlist li { list-style-type: none; } li ul { margin-bottom: 0; } li, dt, dd { font-size: 11px; line-height: 14px; } dt { font-weight: bold; margin-top: 4px; } dd { margin-left: 0; } form { margin: 0; padding: 0; } fieldset { margin: 0; padding: 0; } blockquote { font-size: 11px; color: #777; margin-left: 2px; padding-left: 10px; border-left: 5px solid #ddd; } code, pre { font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background: inherit; color: #666; font-size: 11px; } pre.literal-block { margin: 10px; background: #eee; padding: 6px 8px; } code strong { color: #930; } hr { clear: both; color: #eee; background-color: #eee; height: 1px; border: none; margin: 0; padding: 0; font-size: 1px; line-height: 1px; } /* TEXT STYLES & MODIFIERS */ .small { font-size: 11px; } .tiny { font-size: 10px; } p.tiny { margin-top: -2px; } .mini { font-size: 9px; } p.mini { margin-top: -3px; } .help, p.help { font-size: 10px !important; color: #999; } p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align: middle; } .quiet, a.quiet:link, a.quiet:visited { color: #999 !important; font-weight: normal !important; } .quiet strong { font-weight: bold !important; } .float-right { float: right; } .float-left { float: left; } .clear { clear: both; } .align-left { text-align: left; } .align-right { text-align: right; } .example { margin: 10px 0; padding: 5px 10px; background: #efefef; } .nowrap { white-space: nowrap; } /* TABLES */ table { border-collapse: collapse; border-color: #ccc; } td, th { font-size: 11px; line-height: 13px; border-bottom: 1px solid #eee; vertical-align: top; padding: 5px; font-family: "Lucida Grande", Verdana, Arial, sans-serif; } th { text-align: left; font-size: 12px; font-weight: bold; } thead th, tfoot td { color: #666; padding: 2px 5px; font-size: 11px; background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-left: 1px solid #ddd; border-bottom: 1px solid #ddd; } tfoot td { border-bottom: none; border-top: 1px solid #ddd; } thead th:first-child, tfoot td:first-child { border-left: none !important; } thead th.optional { font-weight: normal !important; } fieldset table { border-right: 1px solid #eee; } tr.row-label td { font-size: 9px; padding-top: 2px; padding-bottom: 0; border-bottom: none; color: #666; margin-top: -1px; } tr.alt { background: #f6f6f6; } .row1 { background: #EDF3FE; } .row2 { background: white; } /* SORTABLE TABLES */ thead th a:link, thead th a:visited { color: #666; display: block; } table thead th.sorted { background-position: bottom left !important; } table thead th.sorted a { padding-right: 13px; } table thead th.ascending a { background: url(../img/admin/arrow-up.gif) right .4em no-repeat; } table thead th.descending a { background: url(../img/admin/arrow-down.gif) right .4em no-repeat; } /* ORDERABLE TABLES */ table.orderable tbody tr td:hover { cursor: move; } table.orderable tbody tr td:first-child { padding-left: 14px; background-image: url(../img/admin/nav-bg-grabber.gif); background-repeat: repeat-y; } table.orderable-initalized .order-cell, body>tr>td.order-cell { display: none; } /* FORM DEFAULTS */ input, textarea, select, .form-row p { margin: 2px 0; padding: 2px 3px; vertical-align: middle; font-family: "Lucida Grande", Verdana, Arial, sans-serif; font-weight: normal; font-size: 11px; } textarea { vertical-align: top !important; } input[type=text], input[type=password], textarea, select, .vTextField { border: 1px solid #ccc; } /* FORM BUTTONS */ .button, input[type=submit], input[type=button], .submit-row input { background: white url(../img/admin/nav-bg.gif) bottom repeat-x; padding: 3px 5px; color: black; border: 1px solid #bbb; border-color: #ddd #aaa #aaa #ddd; } .button:active, input[type=submit]:active, input[type=button]:active { background-image: url(../img/admin/nav-bg-reverse.gif); background-position: top; } .button[disabled], input[type=submit][disabled], input[type=button][disabled] { background-image: url(../img/admin/nav-bg.gif); background-position: bottom; opacity: 0.4; } .button.default, input[type=submit].default, .submit-row input.default { border: 2px solid #5b80b2; background: #7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x; font-weight: bold; color: white; float: right; } .button.default:active, input[type=submit].default:active { background-image: url(../img/admin/default-bg-reverse.gif); background-position: top; } .button[disabled].default, input[type=submit][disabled].default, input[type=button][disabled].default { background-image: url(../img/admin/default-bg.gif); background-position: bottom; opacity: 0.4; } /* MODULES */ .module { border: 1px solid #ccc; margin-bottom: 5px; background: white; } .module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left: 10px; padding-right: 10px; } .module blockquote { margin-left: 12px; } .module ul, .module ol { margin-left: 1.5em; } .module h3 { margin-top: .6em; } .module h2, .module caption, .inline-group h2 { margin: 0; padding: 2px 5px 3px 5px; font-size: 11px; text-align: left; font-weight: bold; background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; color: white; } .module table { border-collapse: collapse; } /* MESSAGES & ERRORS */ ul.messagelist { padding: 0 0 5px 0; margin: 0; } ul.messagelist li { font-size: 12px; display: block; padding: 4px 5px 4px 25px; margin: 0 0 3px 0; border-bottom: 1px solid #ddd; color: #666; background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; } ul.messagelist li.warning{ background-image: url(../img/admin/icon_alert.gif); } ul.messagelist li.error{ background-image: url(../img/admin/icon_error.gif); } .errornote { font-size: 12px !important; display: block; padding: 4px 5px 4px 25px; margin: 0 0 3px 0; border: 1px solid red; color: red; background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } ul.errorlist { margin: 0 !important; padding: 0 !important; } .errorlist li { font-size: 12px !important; display: block; padding: 4px 5px 4px 25px; margin: 0 0 3px 0; border: 1px solid red; color: white; background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; } .errorlist li a { color: white; text-decoration: underline; } td ul.errorlist { margin: 0 !important; padding: 0 !important; } td ul.errorlist li { margin: 0 !important; } .errors { background: #ffc; } .errors input, .errors select, .errors textarea { border: 1px solid red; } div.system-message { background: #ffc; margin: 10px; padding: 6px 8px; font-size: .8em; } div.system-message p.system-message-title { padding: 4px 5px 4px 25px; margin: 0; color: red; background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } .description { font-size: 12px; padding: 5px 0 0 12px; } /* BREADCRUMBS */ div.breadcrumbs { background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding: 2px 8px 3px 8px; font-size: 11px; color: #999; border-top: 1px solid white; border-bottom: 1px solid #ccc; text-align: left; } /* ACTION ICONS */ .addlink { padding-left: 12px; background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; } .changelink { padding-left: 12px; background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; } .deletelink { padding-left: 12px; background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat; } a.deletelink:link, a.deletelink:visited { color: #CC3434; } a.deletelink:hover { color: #993333; } /* OBJECT TOOLS */ .object-tools { font-size: 10px; font-weight: bold; font-family: Arial,Helvetica,sans-serif; padding-left: 0; float: right; position: relative; margin-top: -2.4em; margin-bottom: -2em; } .form-row .object-tools { margin-top: 5px; margin-bottom: 5px; float: none; height: 2em; padding-left: 3.5em; } .object-tools li { display: block; float: left; background: url(../img/admin/tool-left.gif) 0 0 no-repeat; padding: 0 0 0 8px; margin-left: 2px; height: 16px; } .object-tools li:hover { background: url(../img/admin/tool-left_over.gif) 0 0 no-repeat; } .object-tools a:link, .object-tools a:visited { display: block; float: left; color: white; padding: .1em 14px .1em 8px; height: 14px; background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; } .object-tools a:hover, .object-tools li:hover a { background: #5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; } .object-tools a.viewsitelink, .object-tools a.golink { background: #999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; padding-right: 28px; } .object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background: #5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; } .object-tools a.addlink { background: #999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right: 28px; } .object-tools a.addlink:hover { background: #5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; } /* OBJECT HISTORY */ table#change-history { width: 100%; } table#change-history tbody th { width: 16em; } /* PAGE STRUCTURE */ #container { position: relative; width: 100%; min-width: 760px; padding: 0; } #content { margin: 10px 15px; } #header { width: 100%; } #content-main { float: left; width: 100%; } #content-related { float: right; width: 18em; position: relative; margin-right: -19em; } #footer { clear: both; padding: 10px; } /* COLUMN TYPES */ .colMS { margin-right: 20em !important; } .colSM { margin-left: 20em !important; } .colSM #content-related { float: left; margin-right: 0; margin-left: -19em; } .colSM #content-main { float: right; } .popup .colM { width: 95%; } .subcol { float: left; width: 46%; margin-right: 15px; } .dashboard #content { width: 500px; } /* HEADER */ #header { background: #417690; color: #ffc; overflow: hidden; } #header a:link, #header a:visited { color: white; } #header a:hover { text-decoration: underline; } #branding h1 { padding: 0 10px; font-size: 18px; margin: 8px 0; font-weight: normal; color: #f4f379; } #branding h2 { padding: 0 10px; font-size: 14px; margin: -8px 0 8px 0; font-weight: normal; color: #ffc; } #user-tools { position: absolute; top: 0; right: 0; padding: 1.2em 10px; font-size: 11px; text-align: right; } /* SIDEBAR */ #content-related h3 { font-size: 12px; color: #666; margin-bottom: 3px; } #content-related h4 { font-size: 11px; } #content-related .module h2 { background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color: #666; } ================================================ FILE: selfblog/static/admin/css/changelists.css ================================================ /* CHANGELISTS */ #changelist { position: relative; width: 100%; } #changelist table { width: 100%; } .change-list .hiddenfields { display:none; } .change-list .filtered table { border-right: 1px solid #ddd; } .change-list .filtered { min-height: 400px; } .change-list .filtered { background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important; } .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { margin-right: 160px !important; width: auto !important; } .change-list .filtered table tbody th { padding-right: 1em; } #changelist .toplinks { border-bottom: 1px solid #ccc !important; } #changelist .paginator { color: #666; border-top: 1px solid #eee; border-bottom: 1px solid #eee; background: white url(../img/admin/nav-bg.gif) 0 180% repeat-x; overflow: hidden; } .change-list .filtered .paginator { border-right: 1px solid #ddd; } /* CHANGELIST TABLES */ #changelist table thead th { white-space: nowrap; vertical-align: middle; } #changelist table thead th.action-checkbox-column { width: 1.5em; text-align: center; } #changelist table tbody td, #changelist table tbody th { border-left: 1px solid #ddd; } #changelist table tbody td:first-child, #changelist table tbody th:first-child { border-left: 0; border-right: 1px solid #ddd; } #changelist table tbody td.action-checkbox { text-align:center; } #changelist table tfoot { color: #666; } /* TOOLBAR */ #changelist #toolbar { padding: 3px; border-bottom: 1px solid #ddd; background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; color: #666; } #changelist #toolbar form input { font-size: 11px; padding: 1px 2px; } #changelist #toolbar form #searchbar { padding: 2px; } #changelist #changelist-search img { vertical-align: middle; } /* FILTER COLUMN */ #changelist-filter { position: absolute; top: 0; right: 0; z-index: 1000; width: 160px; border-left: 1px solid #ddd; background: #efefef; margin: 0; } #changelist-filter h2 { font-size: 11px; padding: 2px 5px; border-bottom: 1px solid #ddd; } #changelist-filter h3 { font-size: 12px; margin-bottom: 0; } #changelist-filter ul { padding-left: 0; margin-left: 10px; } #changelist-filter li { list-style-type: none; margin-left: 0; padding-left: 0; } #changelist-filter a { color: #999; } #changelist-filter a:hover { color: #036; } #changelist-filter li.selected { border-left: 5px solid #ccc; padding-left: 5px; margin-left: -10px; } #changelist-filter li.selected a { color: #5b80b2 !important; } /* DATE DRILLDOWN */ .change-list ul.toplinks { display: block; background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; border-top: 1px solid white; float: left; padding: 0 !important; margin: 0 !important; width: 100%; } .change-list ul.toplinks li { float: left; width: 9em; padding: 3px 6px; font-weight: bold; list-style-type: none; } .change-list ul.toplinks .date-back a { color: #999; } .change-list ul.toplinks .date-back a:hover { color: #036; } /* PAGINATOR */ .paginator { font-size: 11px; padding-top: 10px; padding-bottom: 10px; line-height: 22px; margin: 0; border-top: 1px solid #ddd; } .paginator a:link, .paginator a:visited { padding: 2px 6px; border: solid 1px #ccc; background: white; text-decoration: none; } .paginator a.showall { padding: 0 !important; border: none !important; } .paginator a.showall:hover { color: #036 !important; background: transparent !important; } .paginator .end { border-width: 2px !important; margin-right: 6px; } .paginator .this-page { padding: 2px 6px; font-weight: bold; font-size: 13px; vertical-align: top; } .paginator a:hover { color: white; background: #5b80b2; border-color: #036; } /* ACTIONS */ .filtered .actions { margin-right: 160px !important; border-right: 1px solid #ddd; } #changelist table input { margin: 0; } #changelist table tbody tr.selected { background-color: #FFFFCC; } #changelist .actions { color: #999; padding: 3px; border-top: 1px solid #fff; border-bottom: 1px solid #ddd; background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; } #changelist .actions.selected { background: #fffccf; border-top: 1px solid #fffee8; border-bottom: 1px solid #edecd6; } #changelist .actions span.all, #changelist .actions span.action-counter, #changelist .actions span.clear, #changelist .actions span.question { font-size: 11px; margin: 0 0.5em; display: none; } #changelist .actions:last-child { border-bottom: none; } #changelist .actions select { border: 1px solid #aaa; margin-left: 0.5em; padding: 1px 2px; } #changelist .actions label { font-size: 11px; margin-left: 0.5em; } #changelist #action-toggle { display: none; } #changelist .actions .button { font-size: 11px; padding: 1px 2px; } ================================================ FILE: selfblog/static/admin/css/dashboard.css ================================================ /* DASHBOARD */ .dashboard .module table th { width: 100%; } .dashboard .module table td { white-space: nowrap; } .dashboard .module table td a { display: block; padding-right: .6em; } /* RECENT ACTIONS MODULE */ .module ul.actionlist { margin-left: 0; } ul.actionlist li { list-style-type: none; } ul.actionlist li.changelink { overflow: hidden; text-overflow: ellipsis; -o-text-overflow: ellipsis; } ================================================ FILE: selfblog/static/admin/css/forms.css ================================================ @import url('widgets.css'); /* FORM ROWS */ .form-row { overflow: hidden; padding: 8px 12px; font-size: 11px; border-bottom: 1px solid #eee; } .form-row img, .form-row input { vertical-align: middle; } form .form-row p { padding-left: 0; font-size: 11px; } /* FORM LABELS */ form h4 { margin: 0 !important; padding: 0 !important; border: none !important; } label { font-weight: normal !important; color: #666; font-size: 12px; } .required label, label.required { font-weight: bold !important; color: #333 !important; } /* RADIO BUTTONS */ form ul.radiolist li { list-style-type: none; } form ul.radiolist label { float: none; display: inline; } form ul.inline { margin-left: 0; padding: 0; } form ul.inline li { float: left; padding-right: 7px; } /* ALIGNED FIELDSETS */ .aligned label { display: block; padding: 3px 10px 0 0; float: left; width: 8em; } .aligned ul label { display: inline; float: none; width: auto; } .colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width: 350px; } form .aligned p, form .aligned ul { margin-left: 7em; padding-left: 30px; } form .aligned table p { margin-left: 0; padding-left: 0; } form .aligned p.help { padding-left: 38px; } .aligned .vCheckboxLabel { float: none !important; display: inline; padding-left: 4px; } .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { width: 610px; } .checkbox-row p.help { margin-left: 0; padding-left: 0 !important; } fieldset .field-box { float: left; margin-right: 20px; } /* WIDE FIELDSETS */ .wide label { width: 15em !important; } form .wide p { margin-left: 15em; } form .wide p.help { padding-left: 38px; } .colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { width: 450px; } /* COLLAPSED FIELDSETS */ fieldset.collapsed * { display: none; } fieldset.collapsed h2, fieldset.collapsed { display: block !important; } fieldset.collapsed h2 { background-image: url(../img/admin/nav-bg.gif); background-position: bottom left; color: #999; } fieldset.collapsed .collapse-toggle { background: transparent; display: inline !important; } /* MONOSPACE TEXTAREAS */ fieldset.monospace textarea { font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; } /* SUBMIT ROW */ .submit-row { padding: 5px 7px; text-align: right; background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x; border: 1px solid #ccc; margin: 5px 0; overflow: hidden; } .submit-row input { margin: 0 0 0 5px; } .submit-row p { margin: 0.3em; } .submit-row p.deletelink-box { float: left; } .submit-row .deletelink { background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; padding-left: 14px; } /* CUSTOM FORM FIELDS */ .vSelectMultipleField { vertical-align: top !important; } .vCheckboxField { border: none; } .vDateField, .vTimeField { margin-right: 2px; } .vURLField { width: 30em; } .vLargeTextField, .vXMLLargeTextField { width: 48em; } .flatpages-flatpage #id_content { height: 40.2em; } .module table .vPositiveSmallIntegerField { width: 2.2em; } .vTextField { width: 20em; } .vIntegerField { width: 5em; } .vForeignKeyRawIdAdminField { width: 5em; } /* INLINES */ .inline-group { padding: 0; border: 1px solid #ccc; margin: 10px 0; } .inline-group .aligned label { width: 8em; } .inline-related { position: relative; } .inline-related h3 { margin: 0; color: #666; padding: 3px 5px; font-size: 11px; background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-bottom: 1px solid #ddd; } .inline-related h3 span.delete { float: right; } .inline-related h3 span.delete label { margin-left: 2px; font-size: 11px; } .inline-related fieldset { margin: 0; background: #fff; border: none; } .inline-related fieldset.module h3 { margin: 0; padding: 2px 5px 3px 5px; font-size: 11px; text-align: left; font-weight: bold; background: #bcd; color: #fff; } .inline-group .tabular fieldset.module { border: none; border-bottom: 1px solid #ddd; } .inline-related.tabular fieldset.module table { width: 100%; } .last-related fieldset { border: none; } .inline-group .tabular tr.has_original td { padding-top: 2em; } .inline-group .tabular tr td.original { padding: 2px 0 0 0; width: 0; _position: relative; } .inline-group .tabular th.original { width: 0px; padding: 0; } .inline-group .tabular td.original p { position: absolute; left: 0; height: 1.1em; padding: 2px 7px; overflow: hidden; font-size: 9px; font-weight: bold; color: #666; _width: 700px; } .inline-group ul.tools { padding: 0; margin: 0; list-style: none; } .inline-group ul.tools li { display: inline; padding: 0 5px; } .inline-group div.add-row, .inline-group .tabular tr.add-row td { color: #666; padding: 3px 5px; border-bottom: 1px solid #ddd; background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; } .inline-group .tabular tr.add-row td { padding: 4px 5px 3px; border-bottom: none; } .inline-group ul.tools a.add, .inline-group div.add-row a, .inline-group .tabular tr.add-row td a { background: url(../img/admin/icon_addlink.gif) 0 50% no-repeat; padding-left: 14px; font-size: 11px; outline: 0; /* Remove dotted border around link */ } .empty-form { display: none; } /* IE7 specific bug fixes */ .submit-row input { float: right; } ================================================ FILE: selfblog/static/admin/css/ie.css ================================================ /* IE 6 & 7 */ /* Proper fixed width for dashboard in IE6 */ .dashboard #content { *width: 768px; } .dashboard #content-main { *width: 535px; } /* IE 6 ONLY */ /* Keep header from flowing off the page */ #container { _position: static; } /* Put the right sidebars back on the page */ .colMS #content-related { _margin-right: 0; _margin-left: 10px; _position: static; } /* Put the left sidebars back on the page */ .colSM #content-related { _margin-right: 10px; _margin-left: -115px; _position: static; } .form-row { _height: 1%; } /* Fix right margin for changelist filters in IE6 */ #changelist-filter ul { _margin-right: -10px; } /* IE ignores min-height, but treats height as if it were min-height */ .change-list .filtered { _height: 400px; } /* IE doesn't know alpha transparency in PNGs */ .inline-deletelink { background: transparent url(../img/admin/inline-delete-8bit.png) no-repeat; } ================================================ FILE: selfblog/static/admin/css/jquery-ui-grappelli-extensions.css ================================================ /* Widget Basics ------------------------------------------------------------------------------------------------------ */ .module.ui-widget { border: none; background: #fff; } .ui-widget-content { border: 1px solid #ccc; border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; background: #eee; } /* Sortable ------------------------------------------------------------------------------------------------------ */ .ui-sortable-helper, .ui-sortable-placeholder { opacity: .8; } .ui-sortable-placeholder, .ui-sortable .module.ui-sortable-placeholder { border: 1px solid #bdbdbd; border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; background: transparent url('../img/backgrounds/ui-sortable-placeholder.png') 0 0 repeat scroll !important; } .group.stacked div.ui-sortable-placeholder { display: block; margin-top: 2px !important; } .group.tabular div.ui-sortable-placeholder { border: 0 !important; overflow: hidden; } .group.tabular .ui-sortable .module.ui-sortable-placeholder .td { background: transparent; } .group.tabular .ui-sortable .module.ui-sortable-placeholder .th, .group.tabular .ui-sortable .module.ui-sortable-placeholder .td { padding-top: 0 !important; padding-bottom: 0 !important; } .group.tabular .module.ui-sortable-helper { border-top: 0 !important; } .group.tabular .ui-sortable-helper .th, .group.tabular .ui-sortable-helper .td { background: #ffffcc !important; } .group.stacked .ui-sortable-helper, .group.stacked .ui-sortable-helper .module, .group.stacked .ui-sortable-helper h2, .group.stacked .ui-sortable-helper h3, .group.stacked .ui-sortable-helper h4, .group.stacked .collapse.predelete.ui-sortable-helper > h3.collapse-handler, .group.stacked .collapse.open.predelete.ui-sortable-helper > h3.collapse-handler, .group.stacked .collapse.predelete.ui-sortable-helper h4.collapse-handler, .group.stacked .collapse.open.predelete.ui-sortable-helper h4.collapse-handler { background: #ffffcc !important; } /* Accordion ------------------------------------------------------------------------------------------------------ */ /* Overlays */ .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } .ui-accordion .ui-accordion-li-fix { display: inline; } .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: 0 0 0 12px; } .ui-accordion .ui-accordion-header .ui-icon { display: none; } .ui-accordion .ui-accordion-content { top: 0; margin-top: 0; margin-bottom: 0; padding: 0; /* border-top: 1px solid #fff;*/ } .ui-accordion .ui-accordion-content-active { display: block; } /* Datepicker ----------------------------------*/ .datetime br { display: none; } .datetimeshortcuts { width: 40px; position: relative; margin-left: 10px; } .datetimeshortcuts a { margin-left: 0 !important; } .ui-accordion-header { margin-top: 2px !important; cursor: pointer; outline: none; } .ui-accordion .ui-accordion-header a { padding: 0 0 0 12px; color: #444; outline: none; } .ui-accordion .ui-accordion-header { display: block; margin: 0; padding: 6px 0; outline: none; font-size: 12px; border: 1px solid #bdbdbd !important; background: #cee9f2; background: -moz-linear-gradient(top, #e1f0f5, #cee9f2); background: -webkit-gradient(linear, left top, left bottom, from(#e1f0f5), to(#cee9f2)); background: -o-linear-gradient(top, #e1f0f5, #cee9f2); } .ui-accordion-header.ui-state-default { border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } .ui-accordion-header.ui-state-hover { background: #cee9f2; background: -moz-linear-gradient(top, #cee9f2, #e1f0f5); background: -webkit-gradient(linear, left top, left bottom, from(#cee9f2), to(#e1f0f5)); background: -o-linear-gradient(top, #cee9f2, #e1f0f5); } .ui-accordion-header.ui-state-active { border-bottom: 1px solid #c7c7c7 !important; border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0; -webkit-border-bottom-left-radius: 0; border-bottom-right-radius: 0; -moz-border-radius-bottomright: 0; -webkit-border-bottom-right-radius: 0; background: #cee9f2; background: -moz-linear-gradient(top, #cee9f2, #e1f0f5); background: -webkit-gradient(linear, left top, left bottom, from(#cee9f2), to(#e1f0f5)); background: -o-linear-gradient(top, #cee9f2, #e1f0f5); } .ui-accordion-content { border-top: 0 !important; border-top-left-radius: 0; -moz-border-radius-topleft: 0; -webkit-border-top-left-radius: 0; border-top-right-radius: 0; -moz-border-radius-topright: 0; -webkit-border-top-right-radius: 0; } .ui-accordion-content h3 { display: none; } .ui-accordion-content .module:first-child { margin-top: 0 !important; border-top-color: #f4f4f4 !important; } .module.accordion>.module { margin-bottom: 2px; border-top: 0 !important; } .module.accordion>.module:last-of-type { margin-bottom: 0; } /* Accordion Module ......................................... */ .ui-accordion-header.ui-state-default, .module .ui-accordion-header.ui-state-default { border: 1px solid #bdbdbd; background-color: #a1d4e5; } .ui-accordion-header.ui-state-default:hover, .module .ui-accordion-header.ui-state-default:hover { background-color: #d6d6d6; } .ui-accordion-header.ui-state-active, .module .ui-accordion-header.ui-state-active { border: 1px solid #bdbdbd; background-color: #d6d6d6; } /* Accordion Module in Group......................................... */ /*.group .module .ui-accordion-header.ui-state-default { border: 1px solid #c7c7c7; background-color: #cee9f2; } .group .module .ui-accordion-header.ui-state-default:hover { background-color: #e0e0e0; } .group .module .ui-accordion-header.ui-state-active { border: 1px solid #c7c7c7; background-color: #e0e0e0; } .group .module .ui-accordion-header { border-top: 1px solid #4ef; } */ /* Datepicker ------------------------------------------------------------------------------------------------------ */ .ui-datepicker { position: absolute; display: none; padding: 3px 3px 0; width: auto !important; border-color: #bdbdbd; box-shadow: 0 10px 50px #333; -moz-box-shadow: 0 10px 50px #333; -webkit-box-shadow: 0 10px 50px #333; } .ui-datepicker .ui-datepicker-header { padding: 2px 0; height: 25px; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next, .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { position: absolute; top: 4px; width: 20px; height: 30px; background-color: transparent; background-position: 50% 50%; background-repeat: no-repeat; cursor: pointer; } .ui-datepicker .ui-datepicker-prev { left: 3px; background-image: url('../img/icons/ui-datepicker-prev.png'); } .ui-datepicker .ui-datepicker-prev-hover { left: 3px; border: none; background-image: url('../img/icons/ui-datepicker-prev-hover.png'); } .ui-datepicker .ui-datepicker-next { right: 3px; background-image: url('../img/icons/ui-datepicker-next.png'); } .ui-datepicker .ui-datepicker-next-hover { right: 3px; border: none; background-image: url('../img/icons/ui-datepicker-next-hover.png'); } .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: none !important; } .ui-datepicker .ui-datepicker-title { margin: 3px 25px 2px; line-height: 1.8em; text-align: center; } .ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin: -3px 0 -1px !important; min-width: 30px; } .ui-datepicker select.ui-datepicker-month-year {width: 100%;} .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { width: 49%;} .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; } .ui-datepicker table { width: 100%; font-size: 12px; margin: 0 0 2px; } .ui-datepicker th { padding: 5px 0; text-align: center; font-weight: bold; border: 0; background: transparent; } .ui-datepicker td { min-width: 25px; border: 0; padding: 1px; } .ui-datepicker td span, .ui-datepicker td a { padding: 4px 0 3px; margin:0!important; text-align: center; display:block; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } .ui-datepicker td a.ui-state-hover { color: #fff !important; border-color: transparent !important; background: #444 !important; } .ui-datepicker td a.ui-state-active { background: #fff; } .ui-datepicker td a.ui-state-highlight { border-color: #bababa; background: #d6d6d6; } .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: 5px 0 0; padding: 0; border: 0; } .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: 3px 0; padding: 4px 5px 5px; height: 25px; color: #aaa; font-size: 11px; border: 1px solid #c7c7c7; background: transparent; cursor: pointer; } @media screen and (-webkit-min-device-pixel-ratio:0) { .ui-datepicker .ui-datepicker-buttonpane button { padding: 5px 8px 4px; } } .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { opacity: 1 !important; color: #444; font-weight: bold; background: #cee9f2; } .ui-datepicker .ui-datepicker-buttonpane button.ui-state-hover { color: #fff !important; border-color: #444 !important; background: #444 !important; } .ui-datepicker-multi .ui-datepicker-group-first .ui-datepicker-title, .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-title { margin-right: 5px !important; } .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-title, .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-title { margin-left: 5px !important; } .ui-datepicker-multi .ui-datepicker-group table { width: 95%; } .ui-datepicker-multi .ui-datepicker-group-first table, .ui-datepicker-multi .ui-datepicker-group-middle table { margin-right: 5px !important; } .ui-datepicker-multi .ui-datepicker-group-middle table, .ui-datepicker-multi .ui-datepicker-group-last table { margin-left: 5px !important; } .ui-datepicker-multi .ui-datepicker-group-middle table { margin-left: 3px !important; } .ui-datepicker-multi .ui-datepicker-buttonpane { border: none; } .ui-datepicker-append { margin-left: 6px; color: #999; font-size: 10px; } .ui-datepicker td.ui-state-disabled { padding:1px; text-align: center; } .ui-datepicker td.ui-state-disabled span { background: #ccc; color: #555 !important; font-weight: bold; font-size: 11px; border-radius: 3px; -moz-border-radius: 3px; -webkit-borderradius: 3px; } button.ui-datepicker-close { float: left !important; margin-right: 4px !important; } /* Timepicker ------------------------------------------------------------------------------------------------------ */ #ui-timepicker { position: absolute; display: none; padding: 5px 3px 3px 5px; width: 216px; border: 1px solid #bdbdbd; box-shadow: 0 10px 50px #333; -moz-box-shadow: 0 10px 50px #333; -webkit-box-shadow: 0 10px 50px #333; } #ui-timepicker ul { position: relative; float: left; clear: both; width: auto; } #ui-timepicker ul li.row { position: relative; float: left; display: block; margin: 0 2px 2px 0; padding: 2px 10px 1px; width: 30px; font-size: 11px; text-align: center; border: 0; border-radius: 3px; -moz-border-radius: 3px; -webkit-borderradius: 3px; cursor: pointer; } #ui-timepicker .row.ui-state-default { border: 1px solid #c7c7c7 !important; background: #e1f0f5; } #ui-timepicker .row.ui-state-active { border: 1px solid #bababa !important; background: #d6d6d6; } #ui-timepicker .row.ui-state-default:hover { color: #fff; border: 1px solid #666 !important; background: #444; } /* Tabs ------------------------------------------------------------------------------------------------------ */ .ui-tabs { zoom: 1; border: 0 !important; background: transparent; } .ui-tabs .ui-tabs-nav { margin-top: 2px; padding: 0; color: #444; font-size: 12px; border: none; border-bottom: 1px solid #bdbdbd; border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0; -webkit-border-bottom-left-radius: 0; background: none; } .ui-tabs:first-child .ui-tabs-nav { margin-top: 0; } .ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 1px !important; margin: 0 2px -1px 0; padding: 0; } .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: 6px 10px 6px; } .ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 0px; border-bottom-width: 1px; } .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ .tab-handler.ui-state-default { background: #e1f0f5; background: -moz-linear-gradient(top, #cee9f2, #e1f0f5); background: -webkit-gradient(linear, left top, left bottom, from(#cee9f2), to(#e1f0f5)); background: -o-linear-gradient(top, #cee9f2, #e1f0f5); } .tab-handler.ui-state-default:hover { color: #444 !important; border: 1px solid #c7c7c7; background: #cee9f2; background: -moz-linear-gradient(top, #e1f0f5, #cee9f2); background: -webkit-gradient(linear, left top, left bottom, from(#e1f0f5), to(#cee9f2)); background: -o-linear-gradient(top, #e1f0f5, #cee9f2); } .tab-handler.ui-state-default.ui-tabs-selected { border: 1px solid #c7c7c7; border-bottom-color: #d4d4d4; background: #e9e9e9; background: -moz-linear-gradient(top, #e0e0e0, #e9e9e9); background: -webkit-gradient(linear, left top, left bottom, from(#e0e0e0), to(#e9e9e9)); background: -o-linear-gradient(top, #e0e0e0, #e9e9e9); } .ui-tabs-nav li a:hover { color: #444 !important; } .ui-tabs-nav li.ui-tabs-selected a { color: #444 !important; } .ui-tabs .ui-tabs-panel { margin-top: 0 !important; padding: 0; display: block; border: 1px solid #ccc; border-top-left-radius: 0; -moz-border-radius-topleft: 0; -webkit-border-top-left-radius: 0; border-top-right-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; background: #eee; } .ui-tabs-panel h3 { display: none; } .ui-tabs-panel > h3 + .module { border-top-right-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; } .ui-tabs-panel > h3 + .module > h4:first-child { margin-top: -1px; /* border-top: 0 !important;*/ border-top-right-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; } .ui-tabs .ui-tabs-hide { display: none !important; } /*.group-accordion-container h3 { display: none; }*/ /* Menu ----------------------------------*/ .ui-menu { list-style:none; padding: 2px; margin: 0; display:block; } .ui-menu .ui-menu { margin-top: -3px; } .ui-menu .ui-menu-item { margin: 0; padding: 0; width: 100%; } .ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 5px 5px 4px; } .ui-menu .ui-menu-item a.ui-state-hover, .ui-menu .ui-menu-item a.ui-state-active { /* margin: -1px;*/ border: 0 !important; } /* Autocomplete ------------------------------------------------------------------------------------------------------ */ .ui-autocomplete { position: absolute; cursor: default; padding: 3px; border: 1px solid #ccc; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; background: #eee; box-shadow: 0 10px 50px #333; -moz-box-shadow: 0 10px 50px #333; -webkit-box-shadow: 0 10px 50px #333; } * html .ui-autocomplete { width: 1px; } .ui-autocomplete-category { font-weight: bold; line-height: 1.5; font-style: italic; margin: 0; padding: 5px; } .ui-autocomplete li:first-child span { display: block; padding: 1px 4px; color: #999; font-weight: bold; } .ui-autocomplete .ui-menu-item + .ui-menu-item { margin-top: 2px; border-top: 0 !important; } .ui-autocomplete li:first-child + li { margin-top: 4px; } .ui-autocomplete .ui-menu-item a { margin: 0; padding: 3px 4px; color: #444; font-weight: bold; border: 1px solid #c7c7c7; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; background: #cee9f2; } .ui-autocomplete .ui-menu-item a.ui-state-hover, .ui-autocomplete .ui-menu-item a:hover, .ui-autocomplete .ui-menu-item a:active { margin: 0 !important; padding: 3px 4px !important; color: #fff !important; border: 1px solid transparent !important; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; background: #444 !important; } ================================================ FILE: selfblog/static/admin/css/login.css ================================================ /* LOGIN FORM */ body.login { background: #eee; } .login #container { background: white; border: 1px solid #ccc; width: 28em; min-width: 300px; margin-left: auto; margin-right: auto; margin-top: 100px; } .login #content-main { width: 100%; } .login form { margin-top: 1em; } .login .form-row { padding: 4px 0; float: left; width: 100%; } .login .form-row label { float: left; width: 9em; padding-right: 0.5em; line-height: 2em; text-align: right; font-size: 1em; color: #333; } .login .form-row #id_username, .login .form-row #id_password { width: 14em; } .login span.help { font-size: 10px; display: block; } .login .submit-row { clear: both; padding: 1em 0 0 9.4em; } ================================================ FILE: selfblog/static/admin/css/rtl.css ================================================ body { direction: rtl; } /* LOGIN */ .login .form-row { float: right; } .login .form-row label { float: right; padding-left: 0.5em; padding-right: 0; text-align: left; } .login .submit-row { clear: both; padding: 1em 9.4em 0 0; } /* GLOBAL */ th { text-align: right; } .module h2, .module caption { text-align: right; } .addlink, .changelink { padding-left: 0px; padding-right: 12px; background-position: 100% 0.2em; } .deletelink { padding-left: 0px; padding-right: 12px; background-position: 100% 0.25em; } .object-tools { float: left; } thead th:first-child, tfoot td:first-child { border-left: 1px solid #ddd !important; } /* LAYOUT */ #user-tools { right: auto; left: 0; text-align: left; } div.breadcrumbs { text-align: right; } #content-main { float: right; } #content-related { float: left; margin-left: -19em; margin-right: auto; } .colMS { margin-left: 20em !important; margin-right: 10px !important; } /* SORTABLE TABLES */ table thead th.sorted a { padding-left: 13px; padding-right: 0px; } table thead th.ascending a, table thead th.descending a { background-position: left; } /* dashboard styles */ .dashboard .module table td a { padding-left: .6em; padding-right: 12px; } /* changelists styles */ .change-list ul.toplinks li { float: right; } .change-list .filtered { background: white url(../img/admin/changelist-bg_rtl.gif) top left repeat-y !important; } .change-list .filtered table { border-left: 1px solid #ddd; border-right: 0px none; } #changelist-filter { right: auto; left: 0; border-left: 0px none; border-right: 1px solid #ddd; } .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { margin-right: 0px !important; margin-left: 160px !important; } #changelist-filter li.selected { border-left: 0px none; padding-left: 0px; margin-left: 0; border-right: 5px solid #ccc; padding-right: 5px; margin-right: -10px; } .filtered .actions { border-left:1px solid #DDDDDD; margin-left:160px !important; border-right: 0 none; margin-right:0 !important; } #changelist table tbody td:first-child, #changelist table tbody th:first-child { border-right: 0; border-left: 1px solid #ddd; } /* FORMS */ .aligned label { padding: 0 0 3px 1em; float: right; } .submit-row { text-align: left } .submit-row p.deletelink-box { float: right; } .submit-row .deletelink { background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; padding-right: 14px; } .vDateField, .vTimeField { margin-left: 2px; } form ul.inline li { float: right; padding-right: 0; padding-left: 7px; } input[type=submit].default, .submit-row input.default { float: left; } fieldset .field-box { float: right; margin-left: 20px; } .errorlist li { background-position: 100% .3em; padding: 4px 25px 4px 5px; } .errornote { background-position: 100% .3em; padding: 4px 25px 4px 5px; } /* WIDGETS */ .calendarnav-previous { top: 0; left: auto; right: 0; } .calendarnav-next { top: 0; right: auto; left: 0; } .calendar caption, .calendarbox h2 { text-align: center; } .selector { float: right; } .selector .selector-filter { text-align: right; } .inline-deletelink { float: left; } /* MISC */ .inline-related h2, .inline-group h2 { text-align: right } .inline-related h3 span.delete { padding-right: 20px; padding-left: inherit; left: 10px; right: inherit; } .inline-related h3 span.delete label { margin-left: inherit; margin-right: 2px; } ================================================ FILE: selfblog/static/admin/css/widgets.css ================================================ /* SELECTOR (FILTER INTERFACE) */ .selector { width: 580px; float: left; } .selector select { width: 270px; height: 17.2em; } .selector-available, .selector-chosen { float: left; width: 270px; text-align: center; margin-bottom: 5px; } .selector-available h2, .selector-chosen h2 { border: 1px solid #ccc; } .selector .selector-available h2 { background: white url(../img/admin/nav-bg.gif) bottom left repeat-x; color: #666; } .selector .selector-filter { background: white; border: 1px solid #ccc; border-width: 0 1px; padding: 3px; color: #999; font-size: 10px; margin: 0; text-align: left; } .selector .selector-chosen .selector-filter { padding: 4px 5px; } .selector .selector-available input { width: 230px; } .selector ul.selector-chooser { float: left; width: 22px; height: 50px; background: url(../img/admin/chooser-bg.gif) top center no-repeat; margin: 8em 3px 0 3px; padding: 0; } .selector-chooser li { margin: 0; padding: 3px; list-style-type: none; } .selector select { margin-bottom: 5px; margin-top: 0; } .selector-add, .selector-remove { width: 16px; height: 16px; display: block; text-indent: -3000px; overflow: hidden; } .selector-add { background: url(../img/admin/selector-add.gif) top center no-repeat; margin-bottom: 2px; } .selector-remove { background: url(../img/admin/selector-remove.gif) top center no-repeat; } a.selector-chooseall, a.selector-clearall { display: block; width: 6em; text-align: left; margin-left: auto; margin-right: auto; font-weight: bold; color: #666; padding: 3px 0 3px 18px; } a.selector-chooseall:hover, a.selector-clearall:hover { color: #036; } a.selector-chooseall { width: 7em; background: url(../img/admin/selector-addall.gif) left center no-repeat; } a.selector-clearall { background: url(../img/admin/selector-removeall.gif) left center no-repeat; } /* STACKED SELECTORS */ .stacked { float: left; width: 500px; } .stacked select { width: 480px; height: 10.1em; } .stacked .selector-available, .stacked .selector-chosen { width: 480px; } .stacked .selector-available { margin-bottom: 0; } .stacked .selector-available input { width: 442px; } .stacked ul.selector-chooser { height: 22px; width: 50px; margin: 0 0 3px 40%; background: url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; } .stacked .selector-chooser li { float: left; padding: 3px 3px 3px 5px; } .stacked .selector-chooseall, .stacked .selector-clearall { display: none; } .stacked .selector-add { background-image: url(../img/admin/selector_stacked-add.gif); } .stacked .selector-remove { background-image: url(../img/admin/selector_stacked-remove.gif); } /* DATE AND TIME */ p.datetime { line-height: 20px; margin: 0; padding: 0; color: #666; font-size: 11px; font-weight: bold; } .datetime span { font-size: 11px; color: #ccc; font-weight: normal; white-space: nowrap; } table p.datetime { font-size: 10px; margin-left: 0; padding-left: 0; } /* FILE UPLOADS */ p.file-upload { line-height: 20px; margin: 0; padding: 0; color: #666; font-size: 11px; font-weight: bold; } .file-upload a { font-weight: normal; } .file-upload .deletelink { margin-left: 5px; } span.clearable-file-input label { color: #333; font-size: 11px; display: inline; float: none; } /* CALENDARS & CLOCKS */ .calendarbox, .clockbox { margin: 5px auto; font-size: 11px; width: 16em; text-align: center; background: white; position: relative; } .clockbox { width: auto; } .calendar { margin: 0; padding: 0; } .calendar table { margin: 0; padding: 0; border-collapse: collapse; background: white; width: 99%; } .calendar caption, .calendarbox h2 { margin: 0; font-size: 11px; text-align: center; border-top: none; } .calendar th { font-size: 10px; color: #666; padding: 2px 3px; text-align: center; background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-bottom: 1px solid #ddd; } .calendar td { font-size: 11px; text-align: center; padding: 0; border-top: 1px solid #eee; border-bottom: none; } .calendar td.selected a { background: #C9DBED; } .calendar td.nonday { background: #efefef; } .calendar td.today a { background: #ffc; } .calendar td a, .timelist a { display: block; font-weight: bold; padding: 4px; text-decoration: none; color: #444; } .calendar td a:hover, .timelist a:hover { background: #5b80b2; color: white; } .calendar td a:active, .timelist a:active { background: #036; color: white; } .calendarnav { font-size: 10px; text-align: center; color: #ccc; margin: 0; padding: 1px 3px; } .calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { color: #999; } .calendar-shortcuts { background: white; font-size: 10px; line-height: 11px; border-top: 1px solid #eee; padding: 3px 0 4px; color: #ccc; } .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { display: block; position: absolute; font-weight: bold; font-size: 12px; background: #C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; padding: 1px 4px 2px 4px; color: white; } .calendarnav-previous:hover, .calendarnav-next:hover { background: #036; } .calendarnav-previous { top: 0; left: 0; } .calendarnav-next { top: 0; right: 0; } .calendar-cancel { margin: 0 !important; padding: 0; font-size: 10px; background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-top: 1px solid #ddd; } .calendar-cancel a { padding: 2px; color: #999; } ul.timelist, .timelist li { list-style-type: none; margin: 0; padding: 0; } .timelist a { padding: 2px; } /* INLINE ORDERER */ ul.orderer { position: relative; padding: 0 !important; margin: 0 !important; list-style-type: none; } ul.orderer li { list-style-type: none; display: block; padding: 0; margin: 0; border: 1px solid #bbb; border-width: 0 1px 1px 0; white-space: nowrap; overflow: hidden; background: #e2e2e2 url(../img/admin/nav-bg-grabber.gif) repeat-y; } ul.orderer li:hover { cursor: move; background-color: #ddd; } ul.orderer li a.selector { margin-left: 12px; overflow: hidden; width: 83%; font-size: 10px !important; padding: 0.6em 0; } ul.orderer li a:link, ul.orderer li a:visited { color: #333; } ul.orderer li .inline-deletelink { position: absolute; right: 4px; margin-top: 0.6em; } ul.orderer li.selected { background-color: #f8f8f8; border-right-color: #f8f8f8; } ul.orderer li.deleted { background: #bbb url(../img/admin/deleted-overlay.gif); } ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited { color: #888; } ul.orderer li.deleted .inline-deletelink { background-image: url(../img/admin/inline-restore.png); } ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { cursor: default; } /* EDIT INLINE */ .inline-deletelink { float: right; text-indent: -9999px; background: transparent url(../img/admin/inline-delete.png) no-repeat; width: 15px; height: 15px; border: 0px none; outline: 0; /* Remove dotted border around link */ } .inline-deletelink:hover { background-position: -15px 0; cursor: pointer; } .editinline button.addlink { border: 0px none; color: #5b80b2; font-size: 100%; cursor: pointer; } .editinline button.addlink:hover { color: #036; cursor: pointer; } .editinline table .help { text-align: right; float: right; padding-left: 2em; } .editinline tfoot .addlink { white-space: nowrap; } .editinline table thead th:last-child { border-left: none; } .editinline tr.deleted { background: #ddd url(../img/admin/deleted-overlay.gif); } .editinline tr.deleted .inline-deletelink { background-image: url(../img/admin/inline-restore.png); } .editinline tr.deleted td:hover { cursor: default; } .editinline tr.deleted td:first-child { background-image: none !important; } /* EDIT INLINE - STACKED */ .editinline-stacked { min-width: 758px; } .editinline-stacked .inline-object { margin-left: 210px; background: white; } .editinline-stacked .inline-source { float: left; width: 200px; background: #f8f8f8; } .editinline-stacked .inline-splitter { float: left; width: 9px; background: #f8f8f8 url(../img/admin/inline-splitter-bg.gif) 50% 50% no-repeat; border-right: 1px solid #ccc; } .editinline-stacked .controls { clear: both; background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; padding: 3px 4px; font-size: 11px; border-top: 1px solid #ddd; } ================================================ FILE: selfblog/static/admin/jquery/i18n/ui.datepicker-de.js ================================================ /* German initialisation for the jQuery UI date picker plugin. */ /* Written by Milian Wolff (mail@milianw.de). */ (function($){ $.datepicker.regional['de'] = { closeText: 'schließen', prevText: '<zurück', nextText: 'Vor>', currentText: 'heute', monthNames: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', 'Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], dateFormat: 'yy-mm-dd', firstDay: 1, isRTL: false}; $.datepicker.setDefaults($.datepicker.regional['de']); })(django.jQuery); ================================================ FILE: selfblog/static/admin/jquery/i18n/ui.datepicker-fr.js ================================================ /* French initialisation for the jQuery UI date picker plugin. */ /* Written by Keith Wood (kbwood@virginbroadband.com.au) and Stéphane Nahmani (sholby@sholby.net). */ (function($){ $.datepicker.regional['fr'] = { closeText: 'Fermer', prevText: '<Préc', nextText: 'Suiv>', currentText: 'Courant', monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', 'Jul','Aoû','Sep','Oct','Nov','Déc'], dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], dateFormat: 'yy-mm-dd', firstDay: 1, isRTL: false}; $.datepicker.setDefaults($.datepicker.regional['fr']); })(django.jQuery); ================================================ FILE: selfblog/static/admin/jquery/jquery.form.js ================================================ /*! * jQuery Form Plugin * version: 2.81 (04-JUN-2011) * @requires jQuery v1.3.2 or later * * Examples and documentation at: http://malsup.com/jquery/form/ * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html */ ;(function($) { /* Usage Note: ----------- Do not use both ajaxSubmit and ajaxForm on the same form. These functions are intended to be exclusive. Use ajaxSubmit if you want to bind your own submit handler to the form. For example, $(document).ready(function() { $('#myForm').bind('submit', function(e) { e.preventDefault(); // <-- important $(this).ajaxSubmit({ target: '#output' }); }); }); Use ajaxForm when you want the plugin to manage all the event binding for you. For example, $(document).ready(function() { $('#myForm').ajaxForm({ target: '#output' }); }); When using ajaxForm, the ajaxSubmit function will be invoked for you at the appropriate time. */ /** * ajaxSubmit() provides a mechanism for immediately submitting * an HTML form using AJAX. */ $.fn.ajaxSubmit = function(options) { // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) if (!this.length) { log('ajaxSubmit: skipping submit process - no element selected'); return this; } if (typeof options == 'function') { options = { success: options }; } var action = this.attr('action'); var url = (typeof action === 'string') ? $.trim(action) : ''; url = url || window.location.href || ''; if (url) { // clean url (don't include hash vaue) url = (url.match(/^([^#]+)/)||[])[1]; } options = $.extend(true, { url: url, success: $.ajaxSettings.success, type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57) iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' }, options); // hook for manipulating the form data before it is extracted; // convenient for use with rich editors like tinyMCE or FCKEditor var veto = {}; this.trigger('form-pre-serialize', [this, options, veto]); if (veto.veto) { log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); return this; } // provide opportunity to alter form data before it is serialized if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { log('ajaxSubmit: submit aborted via beforeSerialize callback'); return this; } var n,v,a = this.formToArray(options.semantic); if (options.data) { options.extraData = options.data; for (n in options.data) { if(options.data[n] instanceof Array) { for (var k in options.data[n]) { a.push( { name: n, value: options.data[n][k] } ); } } else { v = options.data[n]; v = $.isFunction(v) ? v() : v; // if value is fn, invoke it a.push( { name: n, value: v } ); } } } // give pre-submit callback an opportunity to abort the submit if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { log('ajaxSubmit: submit aborted via beforeSubmit callback'); return this; } // fire vetoable 'validate' event this.trigger('form-submit-validate', [a, this, options, veto]); if (veto.veto) { log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); return this; } var q = $.param(a); if (options.type.toUpperCase() == 'GET') { options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; options.data = null; // data is null for 'get' } else { options.data = q; // data is the query string for 'post' } var $form = this, callbacks = []; if (options.resetForm) { callbacks.push(function() { $form.resetForm(); }); } if (options.clearForm) { callbacks.push(function() { $form.clearForm(); }); } // perform a load on the target only if dataType is not provided if (!options.dataType && options.target) { var oldSuccess = options.success || function(){}; callbacks.push(function(data) { var fn = options.replaceTarget ? 'replaceWith' : 'html'; $(options.target)[fn](data).each(oldSuccess, arguments); }); } else if (options.success) { callbacks.push(options.success); } options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg var context = options.context || options; // jQuery 1.4+ supports scope context for (var i=0, max=callbacks.length; i < max; i++) { callbacks[i].apply(context, [data, status, xhr || $form, $form]); } }; // are there files to upload? var fileInputs = $('input:file', this).length > 0; var mp = 'multipart/form-data'; var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); // options.iframe allows user to force iframe mode // 06-NOV-09: now defaulting to iframe mode if file input is detected if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { // hack to fix Safari hang (thanks to Tim Molendijk for this) // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d if (options.closeKeepAlive) { $.get(options.closeKeepAlive, function() { fileUpload(a); }); } else { fileUpload(a); } } else { $.ajax(options); } // fire 'notify' event this.trigger('form-submit-notify', [this, options]); return this; // private function for handling file uploads (hat tip to YAHOO!) function fileUpload(a) { var form = $form[0], i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; if (a) { // ensure that every serialized input is still enabled for (i=0; i < a.length; i++) { $(form[a[i].name]).attr('disabled', false); } } if ($(':input[name=submit],:input[id=submit]', form).length) { // if there is an input with a name or id of 'submit' then we won't be // able to invoke the submit fn on the form (at least not x-browser) alert('Error: Form elements must not have name or id of "submit".'); return; } s = $.extend(true, {}, $.ajaxSettings, options); s.context = s.context || s; id = 'jqFormIO' + (new Date().getTime()); if (s.iframeTarget) { $io = $(s.iframeTarget); n = $io.attr('name'); if (n == null) $io.attr('name', id); else id = n; } else { $io = $('