From 6f74859edcb680f291908a1498d500e66283a591 Mon Sep 17 00:00:00 2001 From: liangliang Date: Sat, 14 Apr 2018 15:47:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E9=83=A8=E5=88=86=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=BD=AC=E7=A7=BB=E6=88=90=E9=85=8D=E7=BD=AE=E8=A1=A8=E5=BD=A2?= =?UTF-8?q?=E5=BC=8F=20close=20#101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DjangoBlog/admin_site.py | 2 ++ DjangoBlog/settings.py | 43 +------------------------ DjangoBlog/utils.py | 25 ++++++++++++++ blog/admin.py | 8 ++--- blog/context_processors.py | 22 +++++++------ blog/models.py | 32 ++++++++++++++++++ blog/templatetags/blog_tags.py | 22 ++++++++----- blog/tests.py | 2 +- oauth/admin.py | 7 +++- oauth/models.py | 29 +++++++++++++++++ oauth/oauthmanager.py | 41 +++++++++++++++-------- oauth/tests.py | 9 ++++++ requirements.txt | 14 ++++---- templates/blog/article_detail.html | 4 +-- templates/blog/tags/article_info.html | 2 +- templates/blog/tags/sidebar.html | 10 ++++-- templates/oauth/oauth_applications.html | 18 ++++++----- templates/share_layout/adsense.html | 12 ++----- travis_test/requirements.txt | 16 ++++----- 19 files changed, 198 insertions(+), 120 deletions(-) diff --git a/DjangoBlog/admin_site.py b/DjangoBlog/admin_site.py index f59fb70..b0fb2a1 100644 --- a/DjangoBlog/admin_site.py +++ b/DjangoBlog/admin_site.py @@ -50,6 +50,7 @@ admin_site.register(Category, CategoryAdmin) admin_site.register(Tag, TagAdmin) admin_site.register(Links, LinksAdmin) admin_site.register(SideBar, SideBarAdmin) +admin_site.register(BlogSettings, BlogSettingsAdmin) admin_site.register(commands, CommandsAdmin) @@ -58,5 +59,6 @@ admin_site.register(BlogUser, BlogUserAdmin) admin_site.register(Comment, CommentAdmin) admin_site.register(OAuthUser, OAuthUserAdmin) +admin_site.register(OAuthConfig, OAuthConfigAdmin) admin_site.register(OwnTrackLog, OwnTrackLogsAdmin) diff --git a/DjangoBlog/settings.py b/DjangoBlog/settings.py index 4ff3763..34abc86 100644 --- a/DjangoBlog/settings.py +++ b/DjangoBlog/settings.py @@ -27,7 +27,7 @@ DEBUG = False TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' # ALLOWED_HOSTS = [] -ALLOWED_HOSTS = ['www.lylinux.net', '127.0.0.1', 'example.com'] +ALLOWED_HOSTS = ['*', 'www.lylinux.net', '127.0.0.1', 'example.com'] # Application definition INSTALLED_APPS = [ @@ -162,23 +162,11 @@ LOGIN_URL = '/login/' TIME_FORMAT = '%Y-%m-%d %H:%M:%S' DATE_TIME_FORMAT = '%Y-%m-%d' -SITE_NAME = '且听风吟' -SITE_URL = 'http://www.lylinux.net' -SITE_DESCRIPTION = '大巧无工,重剑无锋.' -SITE_SEO_DESCRIPTION = '小站主要用来分享和记录学习经验,教程,记录个人生活的点滴以及一些随笔.' -SITE_SEO_KEYWORDS = 'linux,apache,mysql,服务器,ubuntu,shell,web,csharp,.net,asp,mac,swift,python,django' -ARTICLE_SUB_LENGTH = 300 -SHOW_GOOGLE_ADSENSE = False # bootstrap颜色样式 BOOTSTRAP_COLOR_TYPES = [ 'default', 'primary', 'success', 'info', 'warning', 'danger' ] -# 侧边栏文章数目 -SIDEBAR_ARTICLE_COUNT = 10 -# 侧边栏评论数目 -SIDEBAR_COMMENT_COUNT = 5 - # 分页 PAGINATE_BY = 10 # http缓存时间 @@ -197,35 +185,6 @@ CACHES = { 'LOCATION': 'unique-snowflake', } } -# CACHE_MIDDLEWARE_SECONDS = 60 * 60 * 10 -# CACHE_MIDDLEWARE_KEY_PREFIX = "djangoblog" -# CACHE_MIDDLEWARE_ALIAS = 'default' - -# SESSION_ENGINE = "django.contrib.sessions.backends.cache" -# SESSION_CACHE_ALIAS = 'default' - -OAHUTH = { - 'sina': { - 'appkey': os.environ.get('SINA_APP_KEY'), - 'appsecret': os.environ.get('SINA_APP_SECRET'), - 'callbackurl': 'http://www.lylinux.net/oauth/authorize?type=weibo' - }, - 'google': { - 'appkey': os.environ.get('GOOGLE_APP_KEY'), - 'appsecret': os.environ.get('GOOGLE_APP_SECRET'), - 'callbackurl': 'http://www.lylinux.net/oauth/authorize?type=google' - }, - 'github': { - 'appkey': os.environ.get('GITHUB_APP_KEY'), - 'appsecret': os.environ.get('GITHUB_APP_SECRET'), - 'callbackurl': 'http://www.lylinux.net/oauth/authorize?type=github' - }, - 'facebook': { - 'appkey': os.environ.get('FACEBOOK_APP_KEY'), - 'appsecret': os.environ.get('FACEBOOK_APP_SECRET'), - 'callbackurl': 'http://www.lylinux.net/oauth/authorize?type=facebook' - } -} SITE_ID = 1 BAIDU_NOTIFY_URL = "http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn" diff --git a/DjangoBlog/utils.py b/DjangoBlog/utils.py index ae17059..3316c7e 100644 --- a/DjangoBlog/utils.py +++ b/DjangoBlog/utils.py @@ -156,3 +156,28 @@ def parse_dict_to_url(dict): url = '&'.join(['{}={}'.format(quote(k, safe='/'), quote(v, safe='/')) for k, v in dict.items()]) return url + + +def get_blog_setting(): + value = cache.get('get_blog_setting') + if value: + logger.info('get cache get_blog_setting') + return value + else: + from blog.models import BlogSettings + if not BlogSettings.objects.count(): + setting = BlogSettings() + setting.sitename = 'DjangoBlog' + setting.site_description = '基于Django的博客系统' + setting.site_seo_description = '基于Django的博客系统' + setting.site_keywords = 'Django,Python' + setting.article_sub_length = 300 + setting.sidebar_article_count = 10 + setting.sidebar_comment_count = 5 + setting.show_google_adsense = False + setting.open_site_comment = True + setting.save() + value = BlogSettings.objects.first() + logger.info('set cache get_blog_setting') + cache.set('get_blog_setting', value) + return value diff --git a/blog/admin.py b/blog/admin.py index ab4a40a..e8d4aaa 100644 --- a/blog/admin.py +++ b/blog/admin.py @@ -1,15 +1,12 @@ - from django.contrib import admin # Register your models here. -from .models import Article, Category, Tag, Links, SideBar +from .models import Article, Category, Tag, Links, SideBar, BlogSettings from pagedown.widgets import AdminPagedownWidget from django import forms from django.contrib.auth import get_user_model from django.utils.translation import ugettext_lazy as _ - - class ArticleListFilter(admin.SimpleListFilter): title = _("作者") parameter_name = 'author' @@ -105,4 +102,5 @@ class SideBarAdmin(admin.ModelAdmin): exclude = ('last_mod_time', 'created_time') - +class BlogSettingsAdmin(admin.ModelAdmin): + pass diff --git a/blog/context_processors.py b/blog/context_processors.py index b576891..81dbf02 100644 --- a/blog/context_processors.py +++ b/blog/context_processors.py @@ -12,10 +12,10 @@ @file: context_processors.py @time: 2016/11/6 下午4:23 """ -from .models import Category, Article, Tag +from .models import Category, Article, Tag, BlogSettings from django.conf import settings from comments.models import Comment -from DjangoBlog.utils import logger, cache +from DjangoBlog.utils import logger, cache, get_blog_setting def seo_processor(requests): @@ -26,18 +26,20 @@ def seo_processor(requests): return value else: logger.info('set processor cache.') + setting = get_blog_setting() value = { - 'SITE_NAME': settings.SITE_NAME, - 'SHOW_GOOGLE_ADSENSE': settings.SHOW_GOOGLE_ADSENSE, - 'SITE_SEO_DESCRIPTION': settings.SITE_SEO_DESCRIPTION, - 'SITE_DESCRIPTION': settings.SITE_DESCRIPTION, - 'SITE_KEYWORDS': settings.SITE_SEO_KEYWORDS, + 'SITE_NAME': setting.sitename, + 'SHOW_GOOGLE_ADSENSE': setting.show_google_adsense, + 'GOOGLE_ADSENSE_CODES': setting.google_adsense_codes, + 'SITE_SEO_DESCRIPTION': setting.site_seo_description, + 'SITE_DESCRIPTION': setting.site_description, + 'SITE_KEYWORDS': setting.site_keywords, 'SITE_BASE_URL': requests.scheme + '://' + requests.get_host() + '/', - 'ARTICLE_SUB_LENGTH': settings.ARTICLE_SUB_LENGTH, + 'ARTICLE_SUB_LENGTH': setting.article_sub_length, 'nav_category_list': Category.objects.all(), 'nav_pages': Article.objects.filter(type='p', status='p'), - # 'MAX_COMMENTID': Comment.objects.latest().pk, - # 'MAX_ARTICLEID': Article.objects.latest().pk + 'OPEN_SITE_COMMENT': setting.open_site_comment, + } cache.set(key, value, 60 * 60 * 10) return value diff --git a/blog/models.py b/blog/models.py index 38fafd9..0945444 100644 --- a/blog/models.py +++ b/blog/models.py @@ -3,6 +3,8 @@ from django.urls import reverse from django.conf import settings from uuslug import slugify +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ from django.contrib.sites.models import Site from DjangoBlog.utils import cache_decorator, logger, cache from django.utils.functional import cached_property @@ -229,3 +231,33 @@ class SideBar(models.Model): def __str__(self): return self.name + + +class BlogSettings(models.Model): + '''站点设置 ''' + sitename = models.CharField("网站名称", max_length=200, null=False, blank=False, default='') + site_description = models.TextField("网站描述", max_length=1000, null=False, blank=False, default='') + site_seo_description = models.TextField("网站SEO描述", max_length=1000, null=False, blank=False, default='') + site_keywords = models.TextField("网站关键字", max_length=1000, null=False, blank=False, default='') + article_sub_length = models.IntegerField("文章摘要长度", default=300) + sidebar_article_count = models.IntegerField("侧边栏文章数目", default=10) + sidebar_comment_count = models.IntegerField("侧边栏评论数目", default=5) + show_google_adsense = models.BooleanField('是否显示谷歌广告', default=False) + google_adsense_codes = models.TextField('广告内容', max_length=2000, null=True) + open_site_comment = models.BooleanField('是否打开网站评论功能', default=True) + + class Meta: + verbose_name = '网站配置' + verbose_name_plural = verbose_name + + def __str__(self): + return self.sitename + + def clean(self): + if BlogSettings.objects.exclude(id=self.id).count(): + raise ValidationError(_('只能有一个配置')) + + def save(self, *args, **kwargs): + from DjangoBlog.utils import cache + cache.clear() + super().save(*args, **kwargs) diff --git a/blog/templatetags/blog_tags.py b/blog/templatetags/blog_tags.py index 5605b1b..7e0a825 100644 --- a/blog/templatetags/blog_tags.py +++ b/blog/templatetags/blog_tags.py @@ -123,14 +123,16 @@ def load_sidebar(user): :return: """ logger.info('load sidebar') - recent_articles = Article.objects.filter(status='p')[:settings.SIDEBAR_ARTICLE_COUNT] + from DjangoBlog.utils import get_blog_setting + blogsetting = get_blog_setting() + recent_articles = Article.objects.filter(status='p')[:blogsetting.sidebar_article_count] sidebar_categorys = Category.objects.all() extra_sidebars = SideBar.objects.filter(is_enable=True).order_by('sequence') - most_read_articles = Article.objects.filter(status='p').order_by('-views')[:settings.SIDEBAR_ARTICLE_COUNT] + most_read_articles = Article.objects.filter(status='p').order_by('-views')[:blogsetting.sidebar_article_count] dates = Article.objects.datetimes('created_time', 'month', order='DESC') links = Links.objects.all() - commment_list = Comment.objects.filter(is_enable=True).order_by('-id')[:settings.SIDEBAR_COMMENT_COUNT] - show_adsense = settings.SHOW_GOOGLE_ADSENSE + commment_list = Comment.objects.filter(is_enable=True).order_by('-id')[:blogsetting.sidebar_comment_count] + # show_adsense = settings.SHOW_GOOGLE_ADSENSE # 标签云 计算字体大小 # 根据总数计算出平均值 大小为 (数目/平均值)*步长 increment = 5 @@ -150,7 +152,9 @@ def load_sidebar(user): 'sidabar_links': links, 'sidebar_comments': commment_list, 'user': user, - 'show_adsense': show_adsense, + 'show_google_adsense': blogsetting.show_google_adsense, + 'google_adsense_codes': blogsetting.google_adsense_codes, + 'open_site_comment': blogsetting.open_site_comment, 'sidebar_tags': sidebar_tags, 'extra_sidebars': extra_sidebars } @@ -232,10 +236,14 @@ def load_article_detail(article, isindex, user): :param isindex:是否列表页,若是列表页只显示摘要 :return: """ + from DjangoBlog.utils import get_blog_setting + blogsetting = get_blog_setting() + return { 'article': article, 'isindex': isindex, - 'user': user + 'user': user, + 'open_site_comment': blogsetting.open_site_comment, } @@ -275,5 +283,3 @@ def query(qs, **kwargs): {% endfor %} """ return qs.filter(**kwargs) - - diff --git a/blog/tests.py b/blog/tests.py index bb33ac5..d938034 100644 --- a/blog/tests.py +++ b/blog/tests.py @@ -151,7 +151,7 @@ class ArticleTest(TestCase): def test_image(self): import requests - rsp = requests.get('https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2909203028,3998034658&fm=96') + rsp = requests.get('https://www.lylinux.net/static/blog/img/avatar.png') imagepath = os.path.join(settings.BASE_DIR, 'django.jpg') with open(imagepath, 'wb') as file: file.write(rsp.content) diff --git a/oauth/admin.py b/oauth/admin.py index 9f16f04..f86365e 100644 --- a/oauth/admin.py +++ b/oauth/admin.py @@ -1,9 +1,14 @@ from django.contrib import admin # Register your models here. -from .models import OAuthUser +from .models import OAuthUser, OAuthConfig class OAuthUserAdmin(admin.ModelAdmin): list_display = ('id', 'author', 'nikename', 'type', 'picture', 'email',) list_display_links = ('id', 'nikename') list_filter = ('author', 'type',) + + +class OAuthConfigAdmin(admin.ModelAdmin): + list_display = ('type', 'appkey', 'appsecret', 'is_enable') + list_filter = ('type',) diff --git a/oauth/models.py b/oauth/models.py index 4a00c97..cd75175 100644 --- a/oauth/models.py +++ b/oauth/models.py @@ -3,6 +3,8 @@ from django.db import models # Create your models here. from django.conf import settings from django.utils.timezone import now +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ class OAuthUser(models.Model): @@ -24,3 +26,30 @@ class OAuthUser(models.Model): class Meta: verbose_name = 'oauth用户' verbose_name_plural = verbose_name + + +class OAuthConfig(models.Model): + TYPE = ( + ('weibo', '微博'), + ('google', '谷歌'), + ('github', 'GitHub'), + ('facebook', 'FaceBook'), + ) + type = models.CharField('类型', max_length=10, choices=TYPE, default='a') + appkey = models.CharField(max_length=200, verbose_name='AppKey') + appsecret = models.CharField(max_length=200, verbose_name='AppSecret') + callback_url = models.CharField(max_length=200, verbose_name='回调地址', blank=False, default='http://www.baidu.com') + is_enable = models.BooleanField('是否显示', default=True, blank=False, null=False) + created_time = models.DateTimeField('创建时间', default=now) + last_mod_time = models.DateTimeField('修改时间', default=now) + + def clean(self): + if OAuthConfig.objects.filter(type=self.type).exclude(id=self.id).count(): + raise ValidationError(_(self.type + '已经存在')) + + def __str__(self): + return self.type + + class Meta: + verbose_name = 'oauth配置' + verbose_name_plural = verbose_name diff --git a/oauth/oauthmanager.py b/oauth/oauthmanager.py index 5e4f104..45cafe2 100644 --- a/oauth/oauthmanager.py +++ b/oauth/oauthmanager.py @@ -14,7 +14,7 @@ """ from abc import ABCMeta, abstractmethod, abstractproperty -from oauth.models import OAuthUser +from oauth.models import OAuthUser, OAuthConfig from django.conf import settings import requests import json @@ -64,6 +64,10 @@ class BaseOauthManager(metaclass=ABCMeta): rsp = requests.post(url, params) return rsp.text + def get_config(self): + value = OAuthConfig.objects.filter(type=self.ICON_NAME) + return value[0] if value else None + class WBOauthManager(BaseOauthManager): AUTH_URL = 'https://api.weibo.com/oauth2/authorize' @@ -72,9 +76,10 @@ class WBOauthManager(BaseOauthManager): ICON_NAME = 'weibo' def __init__(self, access_token=None, openid=None): - self.client_id = settings.OAHUTH['sina']['appkey'] - self.client_secret = settings.OAHUTH['sina']['appsecret'] - self.callback_url = settings.OAHUTH['sina']['callbackurl'] + config = self.get_config() + self.client_id = config.appkey if config else '' + self.client_secret = config.appsecret if config else '' + self.callback_url = config.callbackurl if config else '' super(WBOauthManager, self).__init__(access_token=access_token, openid=openid) def get_authorization_url(self, nexturl='/'): @@ -137,9 +142,10 @@ class GoogleOauthManager(BaseOauthManager): ICON_NAME = 'google' def __init__(self, access_token=None, openid=None): - self.client_id = settings.OAHUTH['google']['appkey'] - self.client_secret = settings.OAHUTH['google']['appsecret'] - self.callback_url = settings.OAHUTH['google']['callbackurl'] + config = self.get_config() + self.client_id = config.appkey if config else '' + self.client_secret = config.appsecret if config else '' + self.callback_url = config.callbackurl if config else '' super(GoogleOauthManager, self).__init__(access_token=access_token, openid=openid) def get_authorization_url(self, nexturl='/'): @@ -206,9 +212,10 @@ class GitHubOauthManager(BaseOauthManager): ICON_NAME = 'github' def __init__(self, access_token=None, openid=None): - self.client_id = settings.OAHUTH['github']['appkey'] - self.client_secret = settings.OAHUTH['github']['appsecret'] - self.callback_url = settings.OAHUTH['github']['callbackurl'] + config = self.get_config() + self.client_id = config.appkey if config else '' + self.client_secret = config.appsecret if config else '' + self.callback_url = config.callbackurl if config else '' super(GitHubOauthManager, self).__init__(access_token=access_token, openid=openid) def get_authorization_url(self, nexturl='/'): @@ -273,9 +280,10 @@ class FaceBookOauthManager(BaseOauthManager): ICON_NAME = 'facebook' def __init__(self, access_token=None, openid=None): - self.client_id = settings.OAHUTH['facebook']['appkey'] - self.client_secret = settings.OAHUTH['facebook']['appsecret'] - self.callback_url = settings.OAHUTH['facebook']['callbackurl'] + config = self.get_config() + self.client_id = config.appkey if config else '' + self.client_secret = config.appsecret if config else '' + self.callback_url = config.callbackurl if config else '' super(FaceBookOauthManager, self).__init__(access_token=access_token, openid=openid) def get_authorization_url(self, nexturl='/'): @@ -332,8 +340,13 @@ class FaceBookOauthManager(BaseOauthManager): def get_oauth_apps(): + configs = OAuthConfig.objects.filter(is_enable=True).all() + if not configs: + return [] + configtypes = [x.type for x in configs] applications = BaseOauthManager.__subclasses__() - return list(map(lambda x: x(), applications)) + apps = [x for x in applications if configtypes.index(x().ICON_NAME.lower()) >= 0] + return apps def get_manager_by_type(type): diff --git a/oauth/tests.py b/oauth/tests.py index 7ce503c..74568e7 100644 --- a/oauth/tests.py +++ b/oauth/tests.py @@ -1,3 +1,12 @@ from django.test import TestCase +from .models import OAuthConfig + # Create your tests here. +class OAuthConfigTest(TestCase): + def config_save_test(self): + c = OAuthConfig() + c.type = 'weibo' + c.appkey = 'appkey' + c.appsecret = 'appsecret' + c.save() diff --git a/requirements.txt b/requirements.txt index 492d251..7e9049f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,13 +3,13 @@ bottle==0.12.13 certifi==2018.1.18 chardet==3.0.4 coverage==4.5.1 -Django==2.0.3 +Django==2.0.4 django-appconf==1.0.2 django-autoslug==1.9.3 django-compressor==2.2 django-debug-toolbar==1.9.1 -django-haystack==2.8.0 -django-ipware==2.0.1 +django-haystack==2.8.1 +django-ipware==2.0.2 django-pagedown==1.0.4 django-uuslug==1.1.8 idna==2.6 @@ -19,13 +19,13 @@ markdown2==2.3.5 mistune==0.8.3 olefile==0.45.1 packaging==17.1 -Pillow==5.0.0 +Pillow==5.1.0 Pygments==2.2.0 PyMySQL==0.8.0 pyparsing==2.2.0 python-memcached==1.59 -python-slugify==1.2.4 -pytz==2018.3 +python-slugify==1.2.5 +pytz==2018.4 rcssmin==1.0.6 requests==2.18.4 rjsmin==1.0.12 @@ -34,6 +34,6 @@ sqlparse==0.2.4 Unidecode==1.0.22 urllib3==1.22 webencodings==0.5.1 -WeRoBot==1.2.0 +WeRoBot==1.3.0 Whoosh==2.7.4 xmltodict==0.11.0 diff --git a/templates/blog/article_detail.html b/templates/blog/article_detail.html index 13f8d1b..45227e5 100755 --- a/templates/blog/article_detail.html +++ b/templates/blog/article_detail.html @@ -40,7 +40,7 @@ {% endif %} - {% if article.comment_status == "o" %} + {% if article.comment_status == "o" and OPEN_SITE_COMMENT %} {% comment %}{% load comments_tags %} {% load_post_comment article from %}{% endcomment %} @@ -53,7 +53,7 @@ href="{% url "account:login" %}?next={{ request.get_full_path }}">登录后发表评论。 {% load oauth_tags %} - {% load_oauth_applications request%} + {% load_oauth_applications request %} {% endif %} diff --git a/templates/blog/tags/article_info.html b/templates/blog/tags/article_info.html index 44e1b61..a1182ff 100644 --- a/templates/blog/tags/article_info.html +++ b/templates/blog/tags/article_info.html @@ -12,7 +12,7 @@ {% endif %}