diff --git a/DjangoBlog/admin_site.py b/DjangoBlog/admin_site.py
index 87b008a..d90ec5e 100644
--- a/DjangoBlog/admin_site.py
+++ b/DjangoBlog/admin_site.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/DjangoBlog/blog_signals.py b/DjangoBlog/blog_signals.py
index 198f3ff..22260c9 100644
--- a/DjangoBlog/blog_signals.py
+++ b/DjangoBlog/blog_signals.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -34,7 +34,8 @@ import logging
logger = logging.getLogger(__name__)
oauth_user_login_signal = django.dispatch.Signal(providing_args=['id'])
-send_email_signal = django.dispatch.Signal(providing_args=['emailto', 'title', 'content'])
+send_email_signal = django.dispatch.Signal(
+ providing_args=['emailto', 'title', 'content'])
@receiver(send_email_signal)
@@ -43,7 +44,11 @@ def send_email_signal_handler(sender, **kwargs):
title = kwargs['title']
content = kwargs['content']
- msg = EmailMultiAlternatives(title, content, from_email=settings.DEFAULT_FROM_EMAIL, to=emailto)
+ msg = EmailMultiAlternatives(
+ title,
+ content,
+ from_email=settings.DEFAULT_FROM_EMAIL,
+ to=emailto)
msg.content_subtype = "html"
from servermanager.models import EmailSendLog
@@ -77,7 +82,14 @@ def oauth_user_login_signal_handler(sender, **kwargs):
@receiver(post_save)
-def model_post_save_callback(sender, instance, created, raw, using, update_fields, **kwargs):
+def model_post_save_callback(
+ sender,
+ instance,
+ created,
+ raw,
+ using,
+ update_fields,
+ **kwargs):
clearcache = False
if isinstance(instance, LogEntry):
return
@@ -98,10 +110,15 @@ def model_post_save_callback(sender, instance, created, raw, using, update_field
if site.find(':') > 0:
site = site[0:site.find(':')]
- expire_view_cache(path, servername=site, serverport=80, key_prefix='blogdetail')
+ expire_view_cache(
+ path,
+ servername=site,
+ serverport=80,
+ key_prefix='blogdetail')
if cache.get('seo_processor'):
cache.delete('seo_processor')
- comment_cache_key = 'article_comments_{id}'.format(id=instance.article.id)
+ comment_cache_key = 'article_comments_{id}'.format(
+ id=instance.article.id)
cache.delete(comment_cache_key)
delete_sidebar_cache(instance.author.username)
delete_view_cache('article_comments', [str(instance.article.pk)])
diff --git a/DjangoBlog/elasticsearch_backend.py b/DjangoBlog/elasticsearch_backend.py
index e896653..4728ad8 100644
--- a/DjangoBlog/elasticsearch_backend.py
+++ b/DjangoBlog/elasticsearch_backend.py
@@ -29,7 +29,11 @@ logger = logging.getLogger(__name__)
class ElasticSearchBackend(BaseSearchBackend):
def __init__(self, connection_alias, **connection_options):
- super(ElasticSearchBackend, self).__init__(connection_alias, **connection_options)
+ super(
+ ElasticSearchBackend,
+ self).__init__(
+ connection_alias,
+ **connection_options)
self.manager = ArticleDocumentManager()
# try:
# self._rebuild(None)
@@ -75,16 +79,14 @@ class ElasticSearchBackend(BaseSearchBackend):
start_offset = kwargs.get('start_offset')
end_offset = kwargs.get('end_offset')
- q = Q('bool',
- should=[Q('match', body=query_string), Q('match', title=query_string)],
- minimum_should_match="70%"
- )
+ q = Q('bool', should=[Q('match', body=query_string), Q(
+ 'match', title=query_string)], minimum_should_match="70%")
search = ArticleDocument.search() \
- .query('bool', filter=[q]) \
- .filter('term', status='p') \
- .filter('term', type='a') \
- .source(False)[start_offset: end_offset]
+ .query('bool', filter=[q]) \
+ .filter('term', status='p') \
+ .filter('term', type='a') \
+ .source(False)[start_offset: end_offset]
results = search.execute()
hits = results['hits'].total
@@ -99,8 +101,12 @@ class ElasticSearchBackend(BaseSearchBackend):
result_class = SearchResult
- result = result_class(app_label, model_name, raw_result['_id'], raw_result['_score'],
- **additional_fields)
+ result = result_class(
+ app_label,
+ model_name,
+ raw_result['_id'],
+ raw_result['_score'],
+ **additional_fields)
raw_results.append(result)
facets = {}
spelling_suggestion = None
diff --git a/DjangoBlog/logentryadmin.py b/DjangoBlog/logentryadmin.py
index 45b3390..b8a3931 100644
--- a/DjangoBlog/logentryadmin.py
+++ b/DjangoBlog/logentryadmin.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -83,9 +83,9 @@ class LogEntryAdmin(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
return (
- request.user.is_superuser or
- request.user.has_perm('admin.change_logentry')
- ) and request.method != 'POST'
+ request.user.is_superuser or
+ request.user.has_perm('admin.change_logentry')
+ ) and request.method != 'POST'
def has_delete_permission(self, request, obj=None):
return False
diff --git a/DjangoBlog/settings.py b/DjangoBlog/settings.py
index fd7d47d..ffa0dd2 100644
--- a/DjangoBlog/settings.py
+++ b/DjangoBlog/settings.py
@@ -26,7 +26,8 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') or 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'
+SECRET_KEY = os.environ.get(
+ 'DJANGO_SECRET_KEY') or 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env_to_bool('DJANGO_DEBUG', True)
# DEBUG = False
@@ -108,10 +109,11 @@ DATABASES = {
'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root',
'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or 'djangoblog_123',
'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1',
- 'PORT': int(os.environ.get('DJANGO_MYSQL_PORT') or 3306),
- 'OPTIONS': {'charset': 'utf8mb4'},
- }
-}
+ 'PORT': int(
+ os.environ.get('DJANGO_MYSQL_PORT') or 3306),
+ 'OPTIONS': {
+ 'charset': 'utf8mb4'},
+ }}
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
@@ -157,7 +159,8 @@ HAYSTACK_CONNECTIONS = {
# Automatically update searching index
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# Allow user login with username and password
-AUTHENTICATION_BACKENDS = ['accounts.user_login_backend.EmailOrUsernameModelBackend']
+AUTHENTICATION_BACKENDS = [
+ 'accounts.user_login_backend.EmailOrUsernameModelBackend']
STATIC_ROOT = os.path.join(SITE_ROOT, 'collectedstatic')
@@ -195,7 +198,7 @@ CACHES = {
SITE_ID = 1
BAIDU_NOTIFY_URL = os.environ.get('DJANGO_BAIDU_NOTIFY_URL') \
- or 'http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn'
+ or 'http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn'
# Email:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
@@ -210,7 +213,8 @@ SERVER_EMAIL = EMAIL_HOST_USER
# Setting debug=false did NOT handle except email notifications
ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')]
# WX ADMIN password(Two times md5)
-WXADMIN = os.environ.get('DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7'
+WXADMIN = os.environ.get(
+ 'DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7'
LOGGING = {
'version': 1,
diff --git a/DjangoBlog/spider_notify.py b/DjangoBlog/spider_notify.py
index e83ccb1..f88db4e 100644
--- a/DjangoBlog/spider_notify.py
+++ b/DjangoBlog/spider_notify.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/DjangoBlog/tests.py b/DjangoBlog/tests.py
index dfbaa20..5c673bc 100644
--- a/DjangoBlog/tests.py
+++ b/DjangoBlog/tests.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -30,17 +30,17 @@ class DjangoBlogTest(TestCase):
md5 = get_md5('test')
self.assertIsNotNone(md5)
c = CommonMarkdown.get_markdown('''
- # Title1
-
+ # Title1
+
```python
import os
- ```
-
- [url](https://www.lylinux.net/)
-
- [ddd](http://www.baidu.com)
-
-
+ ```
+
+ [url](https://www.lylinux.net/)
+
+ [ddd](http://www.baidu.com)
+
+
''')
self.assertIsNotNone(c)
d = {
diff --git a/DjangoBlog/urls.py b/DjangoBlog/urls.py
index a760104..0bedda9 100644
--- a/DjangoBlog/urls.py
+++ b/DjangoBlog/urls.py
@@ -37,19 +37,20 @@ handler404 = 'blog.views.page_not_found_view'
handler500 = 'blog.views.server_error_view'
handle403 = 'blog.views.permission_denied_view'
urlpatterns = [
- url(r'^admin/', admin_site.urls),
- url(r'', include('blog.urls', namespace='blog')),
- url(r'mdeditor/', include('mdeditor.urls')),
- url(r'', include('comments.urls', namespace='comment')),
- url(r'', include('accounts.urls', namespace='account')),
- url(r'', include('oauth.urls', namespace='oauth')),
- url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
- name='django.contrib.sitemaps.views.sitemap'),
- url(r'^feed/$', DjangoBlogFeed()),
- url(r'^rss/$', DjangoBlogFeed()),
- url(r'^search', include('haystack.urls'), name='search'),
- url(r'', include('servermanager.urls', namespace='servermanager')),
- url(r'', include('owntracks.urls', namespace='owntracks'))
- ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+ url(r'^admin/', admin_site.urls),
+ url(r'', include('blog.urls', namespace='blog')),
+ url(r'mdeditor/', include('mdeditor.urls')),
+ url(r'', include('comments.urls', namespace='comment')),
+ url(r'', include('accounts.urls', namespace='account')),
+ url(r'', include('oauth.urls', namespace='oauth')),
+ url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
+ name='django.contrib.sitemaps.views.sitemap'),
+ url(r'^feed/$', DjangoBlogFeed()),
+ url(r'^rss/$', DjangoBlogFeed()),
+ url(r'^search', include('haystack.urls'), name='search'),
+ url(r'', include('servermanager.urls', namespace='servermanager')),
+ url(r'', include('owntracks.urls', namespace='owntracks'))
+] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
if settings.DEBUG:
- urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+ urlpatterns += static(settings.MEDIA_URL,
+ document_root=settings.MEDIA_ROOT)
diff --git a/DjangoBlog/utils.py b/DjangoBlog/utils.py
index 48ef113..3946dd6 100644
--- a/DjangoBlog/utils.py
+++ b/DjangoBlog/utils.py
@@ -45,7 +45,7 @@ def cache_decorator(expiration=3 * 60):
try:
view = args[0]
key = view.get_cache_key()
- except:
+ except BaseException:
key = None
if not key:
unique_str = repr((func, args, kwargs))
@@ -60,7 +60,9 @@ def cache_decorator(expiration=3 * 60):
else:
return value
else:
- logger.info('cache_decorator set cache:%s key:%s' % (func.__name__, key))
+ logger.info(
+ 'cache_decorator set cache:%s key:%s' %
+ (func.__name__, key))
value = func(*args, **kwargs)
if value is None:
cache.set(key, '__default_cache_value__', expiration)
@@ -120,7 +122,7 @@ def block_code(text, lang, inlinestyles=False, linenos=False):
if linenos:
return '
%s
\n' % code
return code
- except:
+ except BaseException:
return '%s
\n' % (
lang, mistune.escape(text)
)
@@ -163,7 +165,8 @@ class BlogMarkDownRenderer(mistune.Renderer):
if not title:
return '%s' % (link, nofollow, text)
title = escape(title, quote=True)
- return '%s' % (link, title, nofollow, text)
+ return '%s' % (
+ link, title, nofollow, text)
class CommonMarkdown():
@@ -177,7 +180,11 @@ class CommonMarkdown():
def send_email(emailto, title, content):
from DjangoBlog.blog_signals import send_email_signal
- send_email_signal.send(send_email.__class__, emailto=emailto, title=title, content=content)
+ send_email_signal.send(
+ send_email.__class__,
+ emailto=emailto,
+ title=title,
+ content=content)
def parse_dict_to_url(dict):
@@ -225,15 +232,17 @@ def save_user_avatar(url):
try:
imgname = url.split('/')[-1]
if imgname:
- path = r'{basedir}/avatar/{img}'.format(basedir=setting.resource_path, img=imgname)
+ path = r'{basedir}/avatar/{img}'.format(
+ basedir=setting.resource_path, img=imgname)
if os.path.exists(path):
os.remove(path)
- except:
+ except BaseException:
pass
try:
rsp = requests.get(url, timeout=2)
if rsp.status_code == 200:
- basepath = r'{basedir}/avatar/'.format(basedir=setting.resource_path)
+ basepath = r'{basedir}/avatar/'.format(
+ basedir=setting.resource_path)
if not os.path.exists(basepath):
os.makedirs(basepath)
@@ -253,7 +262,10 @@ def save_user_avatar(url):
def delete_sidebar_cache(username):
from django.core.cache.utils import make_template_fragment_key
from blog.models import LINK_SHOW_TYPE
- keys = (make_template_fragment_key('sidebar', [username + x[0]]) for x in LINK_SHOW_TYPE)
+ keys = (
+ make_template_fragment_key(
+ 'sidebar', [
+ username + x[0]]) for x in LINK_SHOW_TYPE)
for k in keys:
logger.info('delete sidebar key:' + k)
cache.delete(k)
diff --git a/DjangoBlog/whoosh_cn_backend.py b/DjangoBlog/whoosh_cn_backend.py
index 5b29a9a..4979e08 100644
--- a/DjangoBlog/whoosh_cn_backend.py
+++ b/DjangoBlog/whoosh_cn_backend.py
@@ -1,6 +1,16 @@
# encoding: utf-8
from __future__ import absolute_import, division, print_function, unicode_literals
+from whoosh.writing import AsyncWriter
+from whoosh.searching import ResultsPage
+from whoosh.qparser import QueryParser
+from whoosh.highlight import ContextFragmenter, HtmlFormatter
+from whoosh.highlight import highlight as whoosh_highlight
+from whoosh.filedb.filestore import FileStorage, RamStorage
+from whoosh.fields import BOOLEAN, DATETIME, IDLIST, KEYWORD, NGRAM, NGRAMWORDS, NUMERIC, Schema, TEXT
+from whoosh.fields import ID as WHOOSH_ID
+from whoosh.analysis import StemmingAnalyzer
+from whoosh import index
from jieba.analyse import ChineseAnalyzer
import json
import os
@@ -32,19 +42,10 @@ except ImportError:
# Handle minimum requirement.
if not hasattr(whoosh, '__version__') or whoosh.__version__ < (2, 5, 0):
- raise MissingDependency("The 'whoosh' backend requires version 2.5.0 or greater.")
+ raise MissingDependency(
+ "The 'whoosh' backend requires version 2.5.0 or greater.")
# Bubble up the correct error.
-from whoosh import index
-from whoosh.analysis import StemmingAnalyzer
-from whoosh.fields import ID as WHOOSH_ID
-from whoosh.fields import BOOLEAN, DATETIME, IDLIST, KEYWORD, NGRAM, NGRAMWORDS, NUMERIC, Schema, TEXT
-from whoosh.filedb.filestore import FileStorage, RamStorage
-from whoosh.highlight import highlight as whoosh_highlight
-from whoosh.highlight import ContextFragmenter, HtmlFormatter
-from whoosh.qparser import QueryParser
-from whoosh.searching import ResultsPage
-from whoosh.writing import AsyncWriter
DATETIME_REGEX = re.compile(
'^(?P\d{4})-(?P\d{2})-(?P\d{2})T(?P\d{2}):(?P\d{2}):(?P\d{2})(\.\d{3,6}Z?)?$')
@@ -71,17 +72,25 @@ class WhooshSearchBackend(BaseSearchBackend):
)
# Characters reserved by Whoosh for special use.
- # The '\\' must come first, so as not to overwrite the other slash replacements.
+ # The '\\' must come first, so as not to overwrite the other slash
+ # replacements.
RESERVED_CHARACTERS = (
'\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}',
'[', ']', '^', '"', '~', '*', '?', ':', '.',
)
def __init__(self, connection_alias, **connection_options):
- super(WhooshSearchBackend, self).__init__(connection_alias, **connection_options)
+ super(
+ WhooshSearchBackend,
+ self).__init__(
+ connection_alias,
+ **connection_options)
self.setup_complete = False
self.use_file_storage = True
- self.post_limit = getattr(connection_options, 'POST_LIMIT', 128 * 1024 * 1024)
+ self.post_limit = getattr(
+ connection_options,
+ 'POST_LIMIT',
+ 128 * 1024 * 1024)
self.path = connection_options.get('PATH')
if connection_options.get('STORAGE', 'file') != 'file':
@@ -89,7 +98,8 @@ class WhooshSearchBackend(BaseSearchBackend):
if self.use_file_storage and not self.path:
raise ImproperlyConfigured(
- "You must specify a 'PATH' in your settings for connection '%s'." % connection_alias)
+ "You must specify a 'PATH' in your settings for connection '%s'." %
+ connection_alias)
self.log = logging.getLogger('haystack')
@@ -106,7 +116,9 @@ class WhooshSearchBackend(BaseSearchBackend):
new_index = True
if self.use_file_storage and not os.access(self.path, os.W_OK):
- raise IOError("The path to your Whoosh index '%s' is not writable for the current user/group." % self.path)
+ raise IOError(
+ "The path to your Whoosh index '%s' is not writable for the current user/group." %
+ self.path)
if self.use_file_storage:
self.storage = FileStorage(self.path)
@@ -146,32 +158,35 @@ class WhooshSearchBackend(BaseSearchBackend):
for field_name, field_class in fields.items():
if field_class.is_multivalued:
if field_class.indexed is False:
- schema_fields[field_class.index_fieldname] = IDLIST(stored=True, field_boost=field_class.boost)
+ schema_fields[field_class.index_fieldname] = IDLIST(
+ stored=True, field_boost=field_class.boost)
else:
- schema_fields[field_class.index_fieldname] = KEYWORD(stored=True, commas=True, scorable=True,
- field_boost=field_class.boost)
+ schema_fields[field_class.index_fieldname] = KEYWORD(
+ stored=True, commas=True, scorable=True, field_boost=field_class.boost)
elif field_class.field_type in ['date', 'datetime']:
- schema_fields[field_class.index_fieldname] = DATETIME(stored=field_class.stored, sortable=True)
+ schema_fields[field_class.index_fieldname] = DATETIME(
+ stored=field_class.stored, sortable=True)
elif field_class.field_type == 'integer':
- schema_fields[field_class.index_fieldname] = NUMERIC(stored=field_class.stored, numtype=int,
- field_boost=field_class.boost)
+ schema_fields[field_class.index_fieldname] = NUMERIC(
+ stored=field_class.stored, numtype=int, field_boost=field_class.boost)
elif field_class.field_type == 'float':
- schema_fields[field_class.index_fieldname] = NUMERIC(stored=field_class.stored, numtype=float,
- field_boost=field_class.boost)
+ schema_fields[field_class.index_fieldname] = NUMERIC(
+ stored=field_class.stored, numtype=float, field_boost=field_class.boost)
elif field_class.field_type == 'boolean':
# Field boost isn't supported on BOOLEAN as of 1.8.2.
- schema_fields[field_class.index_fieldname] = BOOLEAN(stored=field_class.stored)
+ schema_fields[field_class.index_fieldname] = BOOLEAN(
+ stored=field_class.stored)
elif field_class.field_type == 'ngram':
- schema_fields[field_class.index_fieldname] = NGRAM(minsize=3, maxsize=15, stored=field_class.stored,
- field_boost=field_class.boost)
+ schema_fields[field_class.index_fieldname] = NGRAM(
+ minsize=3, maxsize=15, stored=field_class.stored, field_boost=field_class.boost)
elif field_class.field_type == 'edge_ngram':
schema_fields[field_class.index_fieldname] = NGRAMWORDS(minsize=2, maxsize=15, at='start',
stored=field_class.stored,
field_boost=field_class.boost)
else:
# schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)
- schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),
- field_boost=field_class.boost, sortable=True)
+ schema_fields[field_class.index_fieldname] = TEXT(
+ stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)
if field_class.document is True:
content_field_name = field_class.index_fieldname
schema_fields[field_class.index_fieldname].spelling = True
@@ -215,12 +230,18 @@ class WhooshSearchBackend(BaseSearchBackend):
# We'll log the object identifier but won't include the actual object
# to avoid the possibility of that generating encoding errors while
# processing the log message:
- self.log.error(u"%s while preparing object for update" % e.__class__.__name__,
- exc_info=True, extra={"data": {"index": index,
- "object": get_identifier(obj)}})
+ self.log.error(
+ u"%s while preparing object for update" %
+ e.__class__.__name__,
+ exc_info=True,
+ extra={
+ "data": {
+ "index": index,
+ "object": get_identifier(obj)}})
if len(iterable) > 0:
- # For now, commit no matter what, as we run into locking issues otherwise.
+ # For now, commit no matter what, as we run into locking issues
+ # otherwise.
writer.commit()
def remove(self, obj_or_string, commit=True):
@@ -231,12 +252,19 @@ class WhooshSearchBackend(BaseSearchBackend):
whoosh_id = get_identifier(obj_or_string)
try:
- self.index.delete_by_query(q=self.parser.parse(u'%s:"%s"' % (ID, whoosh_id)))
+ self.index.delete_by_query(
+ q=self.parser.parse(
+ u'%s:"%s"' %
+ (ID, whoosh_id)))
except Exception as e:
if not self.silently_fail:
raise
- self.log.error("Failed to remove document '%s' from Whoosh: %s", whoosh_id, e, exc_info=True)
+ self.log.error(
+ "Failed to remove document '%s' from Whoosh: %s",
+ whoosh_id,
+ e,
+ exc_info=True)
def clear(self, models=None, commit=True):
if not self.setup_complete:
@@ -254,18 +282,26 @@ class WhooshSearchBackend(BaseSearchBackend):
models_to_delete = []
for model in models:
- models_to_delete.append(u"%s:%s" % (DJANGO_CT, get_model_ct(model)))
+ models_to_delete.append(
+ u"%s:%s" %
+ (DJANGO_CT, get_model_ct(model)))
- self.index.delete_by_query(q=self.parser.parse(u" OR ".join(models_to_delete)))
+ self.index.delete_by_query(
+ q=self.parser.parse(
+ u" OR ".join(models_to_delete)))
except Exception as e:
if not self.silently_fail:
raise
if models is not None:
- self.log.error("Failed to clear Whoosh index of models '%s': %s", ','.join(models_to_delete),
- e, exc_info=True)
+ self.log.error(
+ "Failed to clear Whoosh index of models '%s': %s",
+ ','.join(models_to_delete),
+ e,
+ exc_info=True)
else:
- self.log.error("Failed to clear Whoosh index: %s", e, exc_info=True)
+ self.log.error(
+ "Failed to clear Whoosh index: %s", e, exc_info=True)
def delete_index(self):
# Per the Whoosh mailing list, if wiping out everything from the index,
@@ -288,7 +324,7 @@ class WhooshSearchBackend(BaseSearchBackend):
def calculate_page(self, start_offset=0, end_offset=None):
# Prevent against Whoosh throwing an error. Requires an end_offset
# greater than 0.
- if not end_offset is None and end_offset <= 0:
+ if end_offset is not None and end_offset <= 0:
end_offset = 1
# Determine the page.
@@ -310,11 +346,26 @@ class WhooshSearchBackend(BaseSearchBackend):
return page_num, page_length
@log_query
- def search(self, query_string, sort_by=None, start_offset=0, end_offset=None,
- fields='', highlight=False, facets=None, date_facets=None, query_facets=None,
- narrow_queries=None, spelling_query=None, within=None,
- dwithin=None, distance_point=None, models=None,
- limit_to_registered_models=None, result_class=None, **kwargs):
+ def search(
+ self,
+ query_string,
+ sort_by=None,
+ start_offset=0,
+ end_offset=None,
+ fields='',
+ highlight=False,
+ facets=None,
+ date_facets=None,
+ query_facets=None,
+ narrow_queries=None,
+ spelling_query=None,
+ within=None,
+ dwithin=None,
+ distance_point=None,
+ models=None,
+ limit_to_registered_models=None,
+ result_class=None,
+ **kwargs):
if not self.setup_complete:
self.setup()
@@ -367,19 +418,29 @@ class WhooshSearchBackend(BaseSearchBackend):
sort_by = sort_by_list[0]
if facets is not None:
- warnings.warn("Whoosh does not handle faceting.", Warning, stacklevel=2)
+ warnings.warn(
+ "Whoosh does not handle faceting.",
+ Warning,
+ stacklevel=2)
if date_facets is not None:
- warnings.warn("Whoosh does not handle date faceting.", Warning, stacklevel=2)
+ warnings.warn(
+ "Whoosh does not handle date faceting.",
+ Warning,
+ stacklevel=2)
if query_facets is not None:
- warnings.warn("Whoosh does not handle query faceting.", Warning, stacklevel=2)
+ warnings.warn(
+ "Whoosh does not handle query faceting.",
+ Warning,
+ stacklevel=2)
narrowed_results = None
self.index = self.index.refresh()
if limit_to_registered_models is None:
- limit_to_registered_models = getattr(settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True)
+ limit_to_registered_models = getattr(
+ settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True)
if models and len(models):
model_choices = sorted(get_model_ct(model) for model in models)
@@ -394,17 +455,19 @@ class WhooshSearchBackend(BaseSearchBackend):
if narrow_queries is None:
narrow_queries = set()
- narrow_queries.add(' OR '.join(['%s:%s' % (DJANGO_CT, rm) for rm in model_choices]))
+ narrow_queries.add(' OR '.join(
+ ['%s:%s' % (DJANGO_CT, rm) for rm in model_choices]))
narrow_searcher = None
if narrow_queries is not None:
- # Potentially expensive? I don't see another way to do it in Whoosh...
+ # Potentially expensive? I don't see another way to do it in
+ # Whoosh...
narrow_searcher = self.index.searcher()
for nq in narrow_queries:
- recent_narrowed_results = narrow_searcher.search(self.parser.parse(force_text(nq)),
- limit=None)
+ recent_narrowed_results = narrow_searcher.search(
+ self.parser.parse(force_text(nq)), limit=None)
if len(recent_narrowed_results) <= 0:
return {
@@ -430,7 +493,8 @@ class WhooshSearchBackend(BaseSearchBackend):
'hits': 0,
}
- page_num, page_length = self.calculate_page(start_offset, end_offset)
+ page_num, page_length = self.calculate_page(
+ start_offset, end_offset)
search_kwargs = {
'pagelen': page_length,
@@ -467,8 +531,12 @@ class WhooshSearchBackend(BaseSearchBackend):
'spelling_suggestion': None,
}
- results = self._process_results(raw_page, highlight=highlight, query_string=query_string,
- spelling_query=spelling_query, result_class=result_class)
+ results = self._process_results(
+ raw_page,
+ highlight=highlight,
+ query_string=query_string,
+ spelling_query=spelling_query,
+ result_class=result_class)
searcher.close()
if hasattr(narrow_searcher, 'close'):
@@ -478,9 +546,11 @@ class WhooshSearchBackend(BaseSearchBackend):
else:
if self.include_spelling:
if spelling_query:
- spelling_suggestion = self.create_spelling_suggestion(spelling_query)
+ spelling_suggestion = self.create_spelling_suggestion(
+ spelling_query)
else:
- spelling_suggestion = self.create_spelling_suggestion(query_string)
+ spelling_suggestion = self.create_spelling_suggestion(
+ query_string)
else:
spelling_suggestion = None
@@ -490,9 +560,16 @@ class WhooshSearchBackend(BaseSearchBackend):
'spelling_suggestion': spelling_suggestion,
}
- def more_like_this(self, model_instance, additional_query_string=None,
- start_offset=0, end_offset=None, models=None,
- limit_to_registered_models=None, result_class=None, **kwargs):
+ def more_like_this(
+ self,
+ model_instance,
+ additional_query_string=None,
+ start_offset=0,
+ end_offset=None,
+ models=None,
+ limit_to_registered_models=None,
+ result_class=None,
+ **kwargs):
if not self.setup_complete:
self.setup()
@@ -506,7 +583,8 @@ class WhooshSearchBackend(BaseSearchBackend):
self.index = self.index.refresh()
if limit_to_registered_models is None:
- limit_to_registered_models = getattr(settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True)
+ limit_to_registered_models = getattr(
+ settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True)
if models and len(models):
model_choices = sorted(get_model_ct(model) for model in models)
@@ -521,7 +599,8 @@ class WhooshSearchBackend(BaseSearchBackend):
if narrow_queries is None:
narrow_queries = set()
- narrow_queries.add(' OR '.join(['%s:%s' % (DJANGO_CT, rm) for rm in model_choices]))
+ narrow_queries.add(' OR '.join(
+ ['%s:%s' % (DJANGO_CT, rm) for rm in model_choices]))
if additional_query_string and additional_query_string != '*':
narrow_queries.add(additional_query_string)
@@ -529,12 +608,13 @@ class WhooshSearchBackend(BaseSearchBackend):
narrow_searcher = None
if narrow_queries is not None:
- # Potentially expensive? I don't see another way to do it in Whoosh...
+ # Potentially expensive? I don't see another way to do it in
+ # Whoosh...
narrow_searcher = self.index.searcher()
for nq in narrow_queries:
- recent_narrowed_results = narrow_searcher.search(self.parser.parse(force_text(nq)),
- limit=None)
+ recent_narrowed_results = narrow_searcher.search(
+ self.parser.parse(force_text(nq)), limit=None)
if len(recent_narrowed_results) <= 0:
return {
@@ -559,7 +639,8 @@ class WhooshSearchBackend(BaseSearchBackend):
results = searcher.search(parsed_query)
if len(results):
- raw_results = results[0].more_like_this(field_name, top=end_offset)
+ raw_results = results[0].more_like_this(
+ field_name, top=end_offset)
# Handle the case where the results have been narrowed.
if narrowed_results is not None and hasattr(raw_results, 'filter'):
@@ -594,7 +675,13 @@ class WhooshSearchBackend(BaseSearchBackend):
return results
- def _process_results(self, raw_page, highlight=False, query_string='', spelling_query=None, result_class=None):
+ def _process_results(
+ self,
+ raw_page,
+ highlight=False,
+ query_string='',
+ spelling_query=None,
+ result_class=None):
from haystack import connections
results = []
@@ -621,15 +708,18 @@ class WhooshSearchBackend(BaseSearchBackend):
index = unified_index.get_index(model)
string_key = str(key)
- if string_key in index.fields and hasattr(index.fields[string_key], 'convert'):
+ if string_key in index.fields and hasattr(
+ index.fields[string_key], 'convert'):
# Special-cased due to the nature of KEYWORD fields.
if index.fields[string_key].is_multivalued:
if value is None or len(value) == 0:
additional_fields[string_key] = []
else:
- additional_fields[string_key] = value.split(',')
+ additional_fields[string_key] = value.split(
+ ',')
else:
- additional_fields[string_key] = index.fields[string_key].convert(value)
+ additional_fields[string_key] = index.fields[string_key].convert(
+ value)
else:
additional_fields[string_key] = self._to_python(value)
@@ -652,16 +742,23 @@ class WhooshSearchBackend(BaseSearchBackend):
self.content_field_name: [whoosh_result],
}
- result = result_class(app_label, model_name, raw_result[DJANGO_ID], score, **additional_fields)
+ result = result_class(
+ app_label,
+ model_name,
+ raw_result[DJANGO_ID],
+ score,
+ **additional_fields)
results.append(result)
else:
hits -= 1
if self.include_spelling:
if spelling_query:
- spelling_suggestion = self.create_spelling_suggestion(spelling_query)
+ spelling_suggestion = self.create_spelling_suggestion(
+ spelling_query)
else:
- spelling_suggestion = self.create_spelling_suggestion(query_string)
+ spelling_suggestion = self.create_spelling_suggestion(
+ query_string)
return {
'results': results,
@@ -742,17 +839,30 @@ class WhooshSearchBackend(BaseSearchBackend):
for dk, dv in date_values.items():
date_values[dk] = int(dv)
- return datetime(date_values['year'], date_values['month'], date_values['day'], date_values['hour'],
- date_values['minute'], date_values['second'])
+ return datetime(
+ date_values['year'],
+ date_values['month'],
+ date_values['day'],
+ date_values['hour'],
+ date_values['minute'],
+ date_values['second'])
try:
# Attempt to use json to load the values.
converted_value = json.loads(value)
# Try to handle most built-in types.
- if isinstance(converted_value, (list, tuple, set, dict, six.integer_types, float, complex)):
+ if isinstance(
+ converted_value,
+ (list,
+ tuple,
+ set,
+ dict,
+ six.integer_types,
+ float,
+ complex)):
return converted_value
- except:
+ except BaseException:
# If it fails (SyntaxError or its ilk) or we don't trust it,
# continue on.
pass
@@ -823,7 +933,8 @@ class WhooshSearchQuery(BaseSearchQuery):
if field == 'content':
index_fieldname = ''
else:
- index_fieldname = u'%s:' % connections[self._using].get_unified_index().get_index_fieldname(field)
+ index_fieldname = u'%s:' % connections[self._using].get_unified_index(
+ ).get_index_fieldname(field)
filter_types = {
'content': '%s',
@@ -841,23 +952,32 @@ class WhooshSearchQuery(BaseSearchQuery):
if value.post_process is False:
query_frag = prepared_value
else:
- if filter_type in ['content', 'contains', 'startswith', 'endswith', 'fuzzy']:
+ if filter_type in [
+ 'content',
+ 'contains',
+ 'startswith',
+ 'endswith',
+ 'fuzzy']:
if value.input_type_name == 'exact':
query_frag = prepared_value
else:
- # Iterate over terms & incorportate the converted form of each into the query.
+ # Iterate over terms & incorportate the converted form of
+ # each into the query.
terms = []
if isinstance(prepared_value, six.string_types):
possible_values = prepared_value.split(' ')
else:
if is_datetime is True:
- prepared_value = self._convert_datetime(prepared_value)
+ prepared_value = self._convert_datetime(
+ prepared_value)
possible_values = [prepared_value]
for possible_value in possible_values:
- terms.append(filter_types[filter_type] % self.backend._from_python(possible_value))
+ terms.append(
+ filter_types[filter_type] %
+ self.backend._from_python(possible_value))
if len(terms) == 1:
query_frag = terms[0]
diff --git a/README.md b/README.md
index b5f5d94..91a8916 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,7 @@ CREATE DATABASE `djangoblog` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8
浏览器打开: http://127.0.0.1:8000/ 就可以看到效果了。
## 更多配置:
[更多配置介绍](/docs/config.md)
+[集成elasticsearch](/docs/es.md)
## 问题相关
diff --git a/accounts/admin.py b/accounts/admin.py
index 67226e4..45ab895 100644
--- a/accounts/admin.py
+++ b/accounts/admin.py
@@ -58,6 +58,13 @@ class BlogUserChangeForm(UserChangeForm):
class BlogUserAdmin(UserAdmin):
form = BlogUserChangeForm
add_form = BlogUserCreationForm
- list_display = ('id', 'nickname', 'username', 'email', 'last_login', 'date_joined', 'source')
+ list_display = (
+ 'id',
+ 'nickname',
+ 'username',
+ 'email',
+ 'last_login',
+ 'date_joined',
+ 'source')
list_display_links = ('id', 'username')
ordering = ('-id',)
diff --git a/accounts/forms.py b/accounts/forms.py
index d8621b0..1f60cd4 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -22,7 +22,8 @@ from django.core.exceptions import ValidationError
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
- self.fields['username'].widget = widgets.TextInput(attrs={'placeholder': "username", "class": "form-control"})
+ self.fields['username'].widget = widgets.TextInput(
+ attrs={'placeholder': "username", "class": "form-control"})
self.fields['password'].widget = widgets.PasswordInput(
attrs={'placeholder': "password", "class": "form-control"})
@@ -31,8 +32,10 @@ class RegisterForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
- self.fields['username'].widget = widgets.TextInput(attrs={'placeholder': "username", "class": "form-control"})
- self.fields['email'].widget = widgets.EmailInput(attrs={'placeholder': "email", "class": "form-control"})
+ self.fields['username'].widget = widgets.TextInput(
+ attrs={'placeholder': "username", "class": "form-control"})
+ self.fields['email'].widget = widgets.EmailInput(
+ attrs={'placeholder': "email", "class": "form-control"})
self.fields['password1'].widget = widgets.PasswordInput(
attrs={'placeholder': "password", "class": "form-control"})
self.fields['password2'].widget = widgets.PasswordInput(
diff --git a/accounts/models.py b/accounts/models.py
index e292dc8..ff6241e 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -14,14 +14,17 @@ class BlogUser(AbstractUser):
source = models.CharField("创建来源", max_length=100, blank=True)
def get_absolute_url(self):
- return reverse('blog:author_detail', kwargs={'author_name': self.username})
+ return reverse(
+ 'blog:author_detail', kwargs={
+ 'author_name': self.username})
def __str__(self):
return self.email
def get_full_url(self):
site = get_current_site().domain
- url = "https://{site}{path}".format(site=site, path=self.get_absolute_url())
+ url = "https://{site}{path}".format(site=site,
+ path=self.get_absolute_url())
return url
class Meta:
diff --git a/accounts/tests.py b/accounts/tests.py
index 37bbcee..77d5e9b 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -18,11 +18,15 @@ class AccountTest(TestCase):
def test_validate_account(self):
site = get_current_site().domain
- user = BlogUser.objects.create_superuser(email="liangliangyy1@gmail.com",
- username="liangliangyy1", password="qwer!@#$ggg")
+ user = BlogUser.objects.create_superuser(
+ email="liangliangyy1@gmail.com",
+ username="liangliangyy1",
+ password="qwer!@#$ggg")
testuser = BlogUser.objects.get(username='liangliangyy1')
- loginresult = self.client.login(username='liangliangyy1', password='qwer!@#$ggg')
+ loginresult = self.client.login(
+ username='liangliangyy1',
+ password='qwer!@#$ggg')
self.assertEqual(loginresult, True)
response = self.client.get('/admin/')
self.assertEqual(response.status_code, 200)
@@ -46,18 +50,25 @@ class AccountTest(TestCase):
self.assertEqual(response.status_code, 200)
def test_validate_register(self):
- self.assertEquals(0, len(BlogUser.objects.filter(email='user123@user.com')))
+ self.assertEquals(
+ 0, len(
+ BlogUser.objects.filter(
+ email='user123@user.com')))
response = self.client.post(reverse('account:register'), {
'username': 'user1233',
'email': 'user123@user.com',
'password1': 'password123!q@wE#R$T',
'password2': 'password123!q@wE#R$T',
})
- self.assertEquals(1, len(BlogUser.objects.filter(email='user123@user.com')))
+ self.assertEquals(
+ 1, len(
+ BlogUser.objects.filter(
+ email='user123@user.com')))
user = BlogUser.objects.filter(email='user123@user.com')[0]
sign = get_md5(get_md5(settings.SECRET_KEY + str(user.id)))
path = reverse('accounts:result')
- url = '{path}?type=validation&id={id}&sign={sign}'.format(path=path, id=user.id, sign=sign)
+ url = '{path}?type=validation&id={id}&sign={sign}'.format(
+ path=path, id=user.id, sign=sign)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
diff --git a/accounts/urls.py b/accounts/urls.py
index a8d1832..a10ff00 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -21,9 +21,16 @@ from .forms import LoginForm
app_name = "accounts"
-urlpatterns = [
- url(r'^login/$', views.LoginView.as_view(success_url='/'), name='login', kwargs={'authentication_form': LoginForm}),
- url(r'^register/$', views.RegisterView.as_view(success_url="/"), name='register'),
- url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
- path(r'account/result.html', views.account_result, name='result')
-]
+urlpatterns = [url(r'^login/$',
+ views.LoginView.as_view(success_url='/'),
+ name='login',
+ kwargs={'authentication_form': LoginForm}),
+ url(r'^register/$',
+ views.RegisterView.as_view(success_url="/"),
+ name='register'),
+ url(r'^logout/$',
+ views.LogoutView.as_view(),
+ name='logout'),
+ path(r'account/result.html',
+ views.account_result,
+ name='result')]
diff --git a/accounts/user_login_backend.py b/accounts/user_login_backend.py
index 74b464a..d26ad09 100644
--- a/accounts/user_login_backend.py
+++ b/accounts/user_login_backend.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/accounts/views.py b/accounts/views.py
index 77a5e4c..6e5f538 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -41,22 +41,28 @@ class RegisterView(FormView):
if settings.DEBUG:
site = '127.0.0.1:8000'
path = reverse('account:result')
- url = "http://{site}{path}?type=validation&id={id}&sign={sign}".format(site=site, path=path, id=user.id,
- sign=sign)
+ url = "http://{site}{path}?type=validation&id={id}&sign={sign}".format(
+ site=site, path=path, id=user.id, sign=sign)
content = """
请点击下面链接验证您的邮箱
-
+
{url}
-
+
再次感谢您!
如果上面链接无法打开,请将此链接复制至浏览器。
{url}
""".format(url=url)
- send_email(emailto=[user.email, ], title='验证您的电子邮箱', content=content)
-
- url = reverse('accounts:result') + '?type=register&id=' + str(user.id)
+ send_email(
+ emailto=[
+ user.email,
+ ],
+ title='验证您的电子邮箱',
+ content=content)
+
+ url = reverse('accounts:result') + \
+ '?type=register&id=' + str(user.id)
return HttpResponseRedirect(url)
else:
return self.render_to_response({
@@ -119,7 +125,9 @@ class LoginView(FormView):
def get_success_url(self):
redirect_to = self.request.POST.get(self.redirect_field_name)
- if not is_safe_url(url=redirect_to, allowed_hosts=[self.request.get_host()]):
+ if not is_safe_url(
+ url=redirect_to, allowed_hosts=[
+ self.request.get_host()]):
redirect_to = self.success_url
return redirect_to
diff --git a/blog/admin.py b/blog/admin.py
index 898686e..f5604bd 100644
--- a/blog/admin.py
+++ b/blog/admin.py
@@ -60,13 +60,25 @@ class ArticlelAdmin(admin.ModelAdmin):
search_fields = ('body', 'title')
form = ArticleForm
list_display = (
- 'id', 'title', 'author', 'link_to_category', 'created_time', 'views', 'status', 'type', 'article_order')
+ 'id',
+ 'title',
+ 'author',
+ 'link_to_category',
+ 'created_time',
+ 'views',
+ 'status',
+ 'type',
+ 'article_order')
list_display_links = ('id', 'title')
list_filter = (ArticleListFilter, 'status', 'type', 'category', 'tags')
filter_horizontal = ('tags',)
exclude = ('created_time', 'last_mod_time')
view_on_site = True
- actions = [makr_article_publish, draft_article, close_article_commentstatus, open_article_commentstatus]
+ actions = [
+ makr_article_publish,
+ draft_article,
+ close_article_commentstatus,
+ open_article_commentstatus]
def link_to_category(self, obj):
info = (obj.category._meta.app_label, obj.category._meta.model_name)
@@ -77,7 +89,8 @@ class ArticlelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super(ArticlelAdmin, self).get_form(request, obj, **kwargs)
- form.base_fields['author'].queryset = get_user_model().objects.filter(is_superuser=True)
+ form.base_fields['author'].queryset = get_user_model(
+ ).objects.filter(is_superuser=True)
return form
def save_model(self, request, obj, form, change):
diff --git a/blog/context_processors.py b/blog/context_processors.py
index 00c8c88..2fb2ad7 100644
--- a/blog/context_processors.py
+++ b/blog/context_processors.py
@@ -39,14 +39,14 @@ def seo_processor(requests):
'SITE_BASE_URL': requests.scheme + '://' + requests.get_host() + '/',
'ARTICLE_SUB_LENGTH': setting.article_sub_length,
'nav_category_list': Category.objects.all(),
- 'nav_pages': Article.objects.filter(type='p', status='p'),
+ 'nav_pages': Article.objects.filter(
+ type='p',
+ status='p'),
'OPEN_SITE_COMMENT': setting.open_site_comment,
'BEIAN_CODE': setting.beiancode,
'ANALYTICS_CODE': setting.analyticscode,
"BEIAN_CODE_GONGAN": setting.gongan_beiancode,
"SHOW_GONGAN_CODE": setting.show_gongan_code,
- "CURRENT_YEAR": datetime.now().year
-
- }
+ "CURRENT_YEAR": datetime.now().year}
cache.set(key, value, 60 * 60 * 10)
return value
diff --git a/blog/documents.py b/blog/documents.py
index 0ea6618..fa382d5 100644
--- a/blog/documents.py
+++ b/blog/documents.py
@@ -3,30 +3,30 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@file: documents.py
@time: 2019-04-05 13:05
"""
+from elasticsearch_dsl.connections import connections
import time
from blog.models import Article, Category, Tag
-from elasticsearch_dsl import Document, Date, Integer, Keyword, Text, Object, Boolean
+from elasticsearch_dsl import Document, Date, Integer, Long, Keyword, Text, Object, Boolean
from django.conf import settings
ELASTICSEARCH_ENABLED = hasattr(settings, 'ELASTICSEARCH_DSL')
-from elasticsearch_dsl.connections import connections
-
if ELASTICSEARCH_ENABLED:
- connections.create_connection(hosts=[settings.ELASTICSEARCH_DSL['default']['hosts']])
+ connections.create_connection(
+ hosts=[settings.ELASTICSEARCH_DSL['default']['hosts']])
class ElapsedTimeDocument(Document):
url = Text()
- time_taken = Integer()
+ time_taken = Long()
log_datetime = Date()
type = Text(analyzer='ik_max_word')
useragent = Text()
@@ -49,8 +49,17 @@ class ElaspedTimeDocumentManager():
# if not hasattr(ElaspedTimeDocumentManager, 'mapping_created'):
# ElapsedTimeDocument.init()
# setattr(ElaspedTimeDocumentManager, 'mapping_created', True)
- doc = ElapsedTimeDocument(meta={'id': int(round(time.time() * 1000))}, url=url, time_taken=time_taken,
- log_datetime=log_datetime, type=type, useragent=useragent)
+ doc = ElapsedTimeDocument(
+ meta={
+ 'id': int(
+ round(
+ time.time() *
+ 1000))},
+ url=url,
+ time_taken=time_taken,
+ log_datetime=log_datetime,
+ type=type,
+ useragent=useragent)
doc.save()
@@ -91,8 +100,7 @@ class ArticleDocument(Document):
class ArticleDocumentManager():
def __init__(self):
- pass
- # ArticleDocument.init()
+ self.create_index()
def create_index(self):
ArticleDocument.init()
@@ -103,23 +111,28 @@ class ArticleDocumentManager():
es.indices.delete(index='blog', ignore=[400, 404])
def convert_to_doc(self, articles):
- return [ArticleDocument(meta={'id': article.id}, body=article.body, title=article.title,
- author={
- 'nikename': article.author.username,
- 'id': article.author.id
- },
- category={
- 'name': article.category.name,
- 'id': article.category.id
- },
- tags=[{'name': t.name, 'id': t.id} for t in article.tags.all()],
- pub_time=article.pub_time,
- status=article.status,
- comment_status=article.comment_status,
- type=article.type,
- views=article.views,
- article_order=article.article_order
- ) for article in articles]
+ return [
+ ArticleDocument(
+ meta={
+ 'id': article.id},
+ body=article.body,
+ title=article.title,
+ author={
+ 'nikename': article.author.username,
+ 'id': article.author.id},
+ category={
+ 'name': article.category.name,
+ 'id': article.category.id},
+ tags=[
+ {
+ 'name': t.name,
+ 'id': t.id} for t in article.tags.all()],
+ pub_time=article.pub_time,
+ status=article.status,
+ comment_status=article.comment_status,
+ type=article.type,
+ views=article.views,
+ article_order=article.article_order) for article in articles]
def rebuild(self, articles=None):
ArticleDocument.init()
diff --git a/blog/forms.py b/blog/forms.py
index 1df8023..5cb1086 100644
--- a/blog/forms.py
+++ b/blog/forms.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/blog/management/commands/build_index.py b/blog/management/commands/build_index.py
index f97a1e0..d8fb12f 100644
--- a/blog/management/commands/build_index.py
+++ b/blog/management/commands/build_index.py
@@ -3,7 +3,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/blog/management/commands/build_search_words.py b/blog/management/commands/build_search_words.py
index 976b2a9..f955ffe 100644
--- a/blog/management/commands/build_search_words.py
+++ b/blog/management/commands/build_search_words.py
@@ -3,7 +3,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -20,5 +20,6 @@ class Command(BaseCommand):
help = 'build search words'
def handle(self, *args, **options):
- datas = set([t.name for t in Tag.objects.all()] + [t.name for t in Category.objects.all()])
+ datas = set([t.name for t in Tag.objects.all()] +
+ [t.name for t in Category.objects.all()])
print('\n'.join(datas))
diff --git a/blog/management/commands/clear_cache.py b/blog/management/commands/clear_cache.py
index f941bf4..0cddbf8 100644
--- a/blog/management/commands/clear_cache.py
+++ b/blog/management/commands/clear_cache.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/blog/management/commands/create_testdata.py b/blog/management/commands/create_testdata.py
index c77ef6a..24a578f 100644
--- a/blog/management/commands/create_testdata.py
+++ b/blog/management/commands/create_testdata.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -24,24 +24,25 @@ class Command(BaseCommand):
help = 'create test datas'
def handle(self, *args, **options):
- user = \
- get_user_model().objects.get_or_create(email='test@test.com', username='测试用户',
- password='test!q@w#eTYU')[0]
+ user = get_user_model().objects.get_or_create(
+ email='test@test.com', username='测试用户', password='test!q@w#eTYU')[0]
- pcategory = Category.objects.get_or_create(name='我是父类目', parent_category=None)[0]
+ pcategory = Category.objects.get_or_create(
+ name='我是父类目', parent_category=None)[0]
- category = Category.objects.get_or_create(name='子类目', parent_category=pcategory)[0]
+ category = Category.objects.get_or_create(
+ name='子类目', parent_category=pcategory)[0]
category.save()
basetag = Tag()
basetag.name = "标签"
basetag.save()
for i in range(1, 20):
- article = Article.objects.get_or_create(category=category,
- title='nice title ' + str(i),
- body='nice content ' + str(i),
- author=user
- )[0]
+ article = Article.objects.get_or_create(
+ category=category,
+ title='nice title ' + str(i),
+ body='nice content ' + str(i),
+ author=user)[0]
tag = Tag()
tag.name = "标签" + str(i)
tag.save()
diff --git a/blog/management/commands/ping_baidu.py b/blog/management/commands/ping_baidu.py
index e97bd0a..14235a0 100644
--- a/blog/management/commands/ping_baidu.py
+++ b/blog/management/commands/ping_baidu.py
@@ -25,8 +25,15 @@ class Command(BaseCommand):
help = 'notify baidu url'
def add_arguments(self, parser):
- parser.add_argument('data_type', type=str, choices=['all', 'article', 'tag', 'category'],
- help='article : all article,tag : all tag,category: all category,all: All of these')
+ parser.add_argument(
+ 'data_type',
+ type=str,
+ choices=[
+ 'all',
+ 'article',
+ 'tag',
+ 'category'],
+ help='article : all article,tag : all tag,category: all category,all: All of these')
def get_full_url(self, path):
url = "https://{site}{path}".format(site=site, path=path)
@@ -49,6 +56,9 @@ class Command(BaseCommand):
url = category.get_absolute_url()
urls.append(self.get_full_url(url))
- self.stdout.write(self.style.SUCCESS('start notify %d urls' % len(urls)))
+ self.stdout.write(
+ self.style.SUCCESS(
+ 'start notify %d urls' %
+ len(urls)))
SpiderNotify.baidu_notify(urls)
self.stdout.write(self.style.SUCCESS('finish notify'))
diff --git a/blog/management/commands/sync_user_avatar.py b/blog/management/commands/sync_user_avatar.py
index 24bf108..0fe86cc 100644
--- a/blog/management/commands/sync_user_avatar.py
+++ b/blog/management/commands/sync_user_avatar.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -30,7 +30,9 @@ class Command(BaseCommand):
url = u.picture
url = save_user_avatar(url)
if url:
- self.stdout.write('结束同步:{id}.url:{url}'.format(id=u.nikename, url=url))
+ self.stdout.write(
+ '结束同步:{id}.url:{url}'.format(
+ id=u.nikename, url=url))
u.picture = url
u.save()
self.stdout.write('结束同步')
diff --git a/blog/middleware.py b/blog/middleware.py
index b30d42a..265e9c4 100644
--- a/blog/middleware.py
+++ b/blog/middleware.py
@@ -41,9 +41,14 @@ class OnlineMiddleware(object):
url = request.path
from django.utils import timezone
- ElaspedTimeDocumentManager.create(url=url, time_taken=time_taken, log_datetime=timezone.now(),
- type='blog', useragent=http_user_agent)
- response.content = response.content.replace(b'', str.encode(str(cast_time)[:5]))
+ ElaspedTimeDocumentManager.create(
+ url=url,
+ time_taken=time_taken,
+ log_datetime=timezone.now(),
+ type='blog',
+ useragent=http_user_agent)
+ response.content = response.content.replace(
+ b'', str.encode(str(cast_time)[:5]))
except Exception as e:
logger.error("Error OnlineMiddleware: %s" % e)
return response
diff --git a/blog/models.py b/blog/models.py
index 720e911..78deeae 100644
--- a/blog/models.py
+++ b/blog/models.py
@@ -29,19 +29,23 @@ class BaseModel(models.Model):
last_mod_time = models.DateTimeField('修改时间', default=now)
def save(self, *args, **kwargs):
- is_update_views = isinstance(self, Article) and 'update_fields' in kwargs and kwargs['update_fields'] == [
- 'views']
+ is_update_views = isinstance(
+ self,
+ Article) and 'update_fields' in kwargs and kwargs['update_fields'] == ['views']
if is_update_views:
Article.objects.filter(pk=self.pk).update(views=self.views)
else:
if 'slug' in self.__dict__:
- slug = getattr(self, 'title') if 'title' in self.__dict__ else getattr(self, 'name')
+ slug = getattr(
+ self, 'title') if 'title' in self.__dict__ else getattr(
+ self, 'name')
setattr(self, 'slug', slugify(slug))
super().save(*args, **kwargs)
def get_full_url(self):
site = get_current_site().domain
- url = "https://{site}{path}".format(site=site, path=self.get_absolute_url())
+ url = "https://{site}{path}".format(site=site,
+ path=self.get_absolute_url())
return url
class Meta:
@@ -68,15 +72,34 @@ class Article(BaseModel):
)
title = models.CharField('标题', max_length=200, unique=True)
body = MDTextField('正文')
- pub_time = models.DateTimeField('发布时间', blank=False, null=False, default=now)
- status = models.CharField('文章状态', max_length=1, choices=STATUS_CHOICES, default='p')
- comment_status = models.CharField('评论状态', max_length=1, choices=COMMENT_STATUS, default='o')
+ pub_time = models.DateTimeField(
+ '发布时间', blank=False, null=False, default=now)
+ status = models.CharField(
+ '文章状态',
+ max_length=1,
+ choices=STATUS_CHOICES,
+ default='p')
+ comment_status = models.CharField(
+ '评论状态',
+ max_length=1,
+ choices=COMMENT_STATUS,
+ default='o')
type = models.CharField('类型', max_length=1, choices=TYPE, default='a')
views = models.PositiveIntegerField('浏览量', default=0)
- author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者', blank=False, null=False,
- on_delete=models.CASCADE)
- article_order = models.IntegerField('排序,数字越大越靠前', blank=False, null=False, default=0)
- category = models.ForeignKey('Category', verbose_name='分类', on_delete=models.CASCADE, blank=False, null=False)
+ author = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ verbose_name='作者',
+ blank=False,
+ null=False,
+ on_delete=models.CASCADE)
+ article_order = models.IntegerField(
+ '排序,数字越大越靠前', blank=False, null=False, default=0)
+ category = models.ForeignKey(
+ 'Category',
+ verbose_name='分类',
+ on_delete=models.CASCADE,
+ blank=False,
+ null=False)
tags = models.ManyToManyField('Tag', verbose_name='标签集合', blank=True)
def body_to_string(self):
@@ -132,7 +155,8 @@ class Article(BaseModel):
@cache_decorator(expiration=60 * 100)
def next_article(self):
# 下一篇
- return Article.objects.filter(id__gt=self.id, status='p').order_by('id').first()
+ return Article.objects.filter(
+ id__gt=self.id, status='p').order_by('id').first()
@cache_decorator(expiration=60 * 100)
def prev_article(self):
@@ -143,7 +167,12 @@ class Article(BaseModel):
class Category(BaseModel):
"""文章分类"""
name = models.CharField('分类名', max_length=30, unique=True)
- parent_category = models.ForeignKey('self', verbose_name="父级分类", blank=True, null=True, on_delete=models.CASCADE)
+ parent_category = models.ForeignKey(
+ 'self',
+ verbose_name="父级分类",
+ blank=True,
+ null=True,
+ on_delete=models.CASCADE)
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
class Meta:
@@ -152,7 +181,9 @@ class Category(BaseModel):
verbose_name_plural = verbose_name
def get_absolute_url(self):
- return reverse('blog:category_detail', kwargs={'category_name': self.slug})
+ return reverse(
+ 'blog:category_detail', kwargs={
+ 'category_name': self.slug})
def __str__(self):
return self.name
@@ -161,7 +192,7 @@ class Category(BaseModel):
def get_category_tree(self):
"""
递归获得分类目录的父级
- :return:
+ :return:
"""
categorys = []
@@ -177,7 +208,7 @@ class Category(BaseModel):
def get_sub_categorys(self):
"""
获得当前分类目录所有子集
- :return:
+ :return:
"""
categorys = []
all_categorys = Category.objects.all()
@@ -222,8 +253,13 @@ class Links(models.Model):
name = models.CharField('链接名称', max_length=30, unique=True)
link = models.URLField('链接地址')
sequence = models.IntegerField('排序', unique=True)
- is_enable = models.BooleanField('是否显示', default=True, blank=False, null=False)
- show_type = models.CharField('显示类型', max_length=1, choices=LINK_SHOW_TYPE, default='i')
+ is_enable = models.BooleanField(
+ '是否显示', default=True, blank=False, null=False)
+ show_type = models.CharField(
+ '显示类型',
+ max_length=1,
+ choices=LINK_SHOW_TYPE,
+ default='i')
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
@@ -256,21 +292,58 @@ class SideBar(models.Model):
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='')
+ 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, blank=True, default='')
+ google_adsense_codes = models.TextField(
+ '广告内容', max_length=2000, null=True, blank=True, default='')
open_site_comment = models.BooleanField('是否打开网站评论功能', default=True)
- beiancode = models.CharField('备案号', max_length=2000, null=True, blank=True, default='')
- analyticscode = models.TextField("网站统计代码", max_length=1000, null=False, blank=False, default='')
- show_gongan_code = models.BooleanField('是否显示公安备案号', default=False, null=False)
- gongan_beiancode = models.TextField('公安备案号', max_length=2000, null=True, blank=True, default='')
- resource_path = models.CharField("静态文件保存地址", max_length=300, null=False, default='/var/www/resource/')
+ beiancode = models.CharField(
+ '备案号',
+ max_length=2000,
+ null=True,
+ blank=True,
+ default='')
+ analyticscode = models.TextField(
+ "网站统计代码",
+ max_length=1000,
+ null=False,
+ blank=False,
+ default='')
+ show_gongan_code = models.BooleanField(
+ '是否显示公安备案号', default=False, null=False)
+ gongan_beiancode = models.TextField(
+ '公安备案号',
+ max_length=2000,
+ null=True,
+ blank=True,
+ default='')
+ resource_path = models.CharField(
+ "静态文件保存地址",
+ max_length=300,
+ null=False,
+ default='/var/www/resource/')
class Meta:
verbose_name = '网站配置'
diff --git a/blog/search_indexes.py b/blog/search_indexes.py
index ed80e65..e14349e 100644
--- a/blog/search_indexes.py
+++ b/blog/search_indexes.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/blog/templatetags/blog_tags.py b/blog/templatetags/blog_tags.py
index 760f8d5..dc8ee3a 100644
--- a/blog/templatetags/blog_tags.py
+++ b/blog/templatetags/blog_tags.py
@@ -135,13 +135,18 @@ def load_sidebar(user, linktype):
logger.info('load sidebar')
from DjangoBlog.utils import get_blog_setting
blogsetting = get_blog_setting()
- recent_articles = Article.objects.filter(status='p')[:blogsetting.sidebar_article_count]
+ 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')[:blogsetting.sidebar_article_count]
+ extra_sidebars = SideBar.objects.filter(
+ is_enable=True).order_by('sequence')
+ 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.filter(is_enable=True).filter(Q(show_type=str(linktype)) | Q(show_type='a'))
- commment_list = Comment.objects.filter(is_enable=True).order_by('-id')[:blogsetting.sidebar_comment_count]
+ links = Links.objects.filter(is_enable=True).filter(
+ Q(show_type=str(linktype)) | Q(show_type='a'))
+ commment_list = Comment.objects.filter(is_enable=True).order_by(
+ '-id')[:blogsetting.sidebar_comment_count]
# 标签云 计算字体大小
# 根据总数计算出平均值 大小为 (数目/平均值)*步长
increment = 5
@@ -152,7 +157,8 @@ def load_sidebar(user, linktype):
count = sum([t[1] for t in s])
dd = 1 if (count == 0 or not len(tags)) else count / len(tags)
import random
- sidebar_tags = list(map(lambda x: (x[0], x[1], (x[1] / dd) * increment + 10), s))
+ sidebar_tags = list(
+ map(lambda x: (x[0], x[1], (x[1] / dd) * increment + 10), s))
random.shuffle(sidebar_tags)
return {
@@ -195,33 +201,57 @@ def load_pagination_info(page_obj, page_type, tag_name):
next_url = reverse('blog:index_page', kwargs={'page': next_number})
if page_obj.has_previous():
previous_number = page_obj.previous_page_number()
- previous_url = reverse('blog:index_page', kwargs={'page': previous_number})
+ previous_url = reverse(
+ 'blog:index_page', kwargs={
+ 'page': previous_number})
if page_type == '分类标签归档':
tag = get_object_or_404(Tag, name=tag_name)
if page_obj.has_next():
next_number = page_obj.next_page_number()
- next_url = reverse('blog:tag_detail_page', kwargs={'page': next_number, 'tag_name': tag.slug})
+ next_url = reverse(
+ 'blog:tag_detail_page',
+ kwargs={
+ 'page': next_number,
+ 'tag_name': tag.slug})
if page_obj.has_previous():
previous_number = page_obj.previous_page_number()
- previous_url = reverse('blog:tag_detail_page', kwargs={'page': previous_number, 'tag_name': tag.slug})
+ previous_url = reverse(
+ 'blog:tag_detail_page',
+ kwargs={
+ 'page': previous_number,
+ 'tag_name': tag.slug})
if page_type == '作者文章归档':
if page_obj.has_next():
next_number = page_obj.next_page_number()
- next_url = reverse('blog:author_detail_page', kwargs={'page': next_number, 'author_name': tag_name})
+ next_url = reverse(
+ 'blog:author_detail_page',
+ kwargs={
+ 'page': next_number,
+ 'author_name': tag_name})
if page_obj.has_previous():
previous_number = page_obj.previous_page_number()
- previous_url = reverse('blog:author_detail_page', kwargs={'page': previous_number, 'author_name': tag_name})
+ previous_url = reverse(
+ 'blog:author_detail_page',
+ kwargs={
+ 'page': previous_number,
+ 'author_name': tag_name})
if page_type == '分类目录归档':
category = get_object_or_404(Category, name=tag_name)
if page_obj.has_next():
next_number = page_obj.next_page_number()
- next_url = reverse('blog:category_detail_page',
- kwargs={'page': next_number, 'category_name': category.slug})
+ next_url = reverse(
+ 'blog:category_detail_page',
+ kwargs={
+ 'page': next_number,
+ 'category_name': category.slug})
if page_obj.has_previous():
previous_number = page_obj.previous_page_number()
- previous_url = reverse('blog:category_detail_page',
- kwargs={'page': previous_number, 'category_name': category.slug})
+ previous_url = reverse(
+ 'blog:category_detail_page',
+ kwargs={
+ 'page': previous_number,
+ 'category_name': category.slug})
return {
'previous_url': previous_url,
@@ -275,10 +305,11 @@ def gravatar_url(email, size=40):
return o[0].picture
email = email.encode('utf-8')
- default = "https://resource.lylinux.net/image/2017/03/26/120117.jpg".encode('utf-8')
+ default = "https://resource.lylinux.net/image/2017/03/26/120117.jpg".encode(
+ 'utf-8')
- url = "https://www.gravatar.com/avatar/%s?%s" % (
- hashlib.md5(email.lower()).hexdigest(), urllib.parse.urlencode({'d': default, 's': str(size)}))
+ url = "https://www.gravatar.com/avatar/%s?%s" % (hashlib.md5(
+ email.lower()).hexdigest(), urllib.parse.urlencode({'d': default, 's': str(size)}))
cache.set(cachekey, url, 60 * 60 * 10)
return url
@@ -287,7 +318,9 @@ def gravatar_url(email, size=40):
def gravatar(email, size=40):
"""获得gravatar头像"""
url = gravatar_url(email, size)
- return mark_safe('
' % (url, size, size))
+ return mark_safe(
+ '
' %
+ (url, size, size))
@register.simple_tag
diff --git a/blog/tests.py b/blog/tests.py
index 876fbe7..d1ce069 100644
--- a/blog/tests.py
+++ b/blog/tests.py
@@ -22,7 +22,9 @@ class ArticleTest(TestCase):
def test_validate_article(self):
site = get_current_site().domain
- user = BlogUser.objects.get_or_create(email="liangliangyy@gmail.com", username="liangliangyy")[0]
+ user = BlogUser.objects.get_or_create(
+ email="liangliangyy@gmail.com",
+ username="liangliangyy")[0]
user.set_password("liangliangyy")
user.is_staff = True
user.is_superuser = True
@@ -104,7 +106,9 @@ class ArticleTest(TestCase):
p = Paginator(Article.objects.filter(tags=tag), 2)
self.__check_pagination__(p, '分类标签归档', tag.slug)
- p = Paginator(Article.objects.filter(author__username='liangliangyy'), 2)
+ p = Paginator(
+ Article.objects.filter(
+ author__username='liangliangyy'), 2)
self.__check_pagination__(p, '作者文章归档', 'liangliangyy')
p = Paginator(Article.objects.filter(category=category), 2)
@@ -120,7 +124,10 @@ class ArticleTest(TestCase):
u = gravatar_url('liangliangyy@gmail.com')
u = gravatar('liangliangyy@gmail.com')
- link = Links(sequence=1, name="lylinux", link='https://wwww.lylinux.net')
+ link = Links(
+ sequence=1,
+ name="lylinux",
+ link='https://wwww.lylinux.net')
link.save()
response = self.client.get('/links.html')
self.assertEqual(response.status_code, 200)
@@ -141,7 +148,9 @@ class ArticleTest(TestCase):
self.assertEqual(response.status_code, 200)
def test_validate_feed(self):
- user = BlogUser.objects.get_or_create(email="liangliangyy12@gmail.com", username="liangliangyy")[0]
+ user = BlogUser.objects.get_or_create(
+ email="liangliangyy12@gmail.com",
+ username="liangliangyy")[0]
user.set_password("liangliangyy")
user.save()
self.client.login(username='liangliangyy', password='liangliangyy')
@@ -157,7 +166,8 @@ class ArticleTest(TestCase):
def test_image(self):
import requests
- rsp = requests.get('https://www.python.org/static/img/python-logo@2x.png')
+ rsp = requests.get(
+ 'https://www.python.org/static/img/python-logo@2x.png')
imagepath = os.path.join(settings.BASE_DIR, 'python.png')
with open(imagepath, 'wb') as file:
file.write(rsp.content)
@@ -165,14 +175,17 @@ class ArticleTest(TestCase):
self.assertEqual(rsp.status_code, 403)
sign = get_md5(get_md5(settings.SECRET_KEY))
with open(imagepath, 'rb') as file:
- imgfile = SimpleUploadedFile('python.png', file.read(), content_type='image/jpg')
+ imgfile = SimpleUploadedFile(
+ 'python.png', file.read(), content_type='image/jpg')
form_data = {'python.png': imgfile}
- rsp = self.client.post('/upload?sign=' + sign, form_data, follow=True)
+ rsp = self.client.post(
+ '/upload?sign=' + sign, form_data, follow=True)
self.assertEqual(rsp.status_code, 200)
from DjangoBlog.utils import save_user_avatar, send_email
send_email(['qq@qq.com'], 'testTitle', 'testContent')
- save_user_avatar('https://www.python.org/static/img/python-logo@2x.png')
+ save_user_avatar(
+ 'https://www.python.org/static/img/python-logo@2x.png')
"""
data = SimpleUploadedFile(imagepath, b'file_content', content_type='image/jpg')
rsp = self.client.post('/upload', {'django.jpg': data})
diff --git a/blog/urls.py b/blog/urls.py
index df2e6a8..883847c 100644
--- a/blog/urls.py
+++ b/blog/urls.py
@@ -22,26 +22,57 @@ from haystack.views import SearchView
app_name = "blog"
urlpatterns = [
- path(r'', views.IndexView.as_view(), name='index'),
- path(r'page//', views.IndexView.as_view(), name='index_page'),
-
- path(r'article////.html',
- views.ArticleDetailView.as_view(),
- name='detailbyid'),
-
- path(r'category/.html', views.CategoryDetailView.as_view(), name='category_detail'),
- path(r'category//.html', views.CategoryDetailView.as_view(),
- name='category_detail_page'),
-
- path(r'author/.html', views.AuthorDetailView.as_view(), name='author_detail'),
- path(r'author//.html', views.AuthorDetailView.as_view(),
- name='author_detail_page'),
-
- path(r'tag/.html', views.TagDetailView.as_view(), name='tag_detail'),
- path(r'tag//.html', views.TagDetailView.as_view(), name='tag_detail_page'),
- path('archives.html', cache_page(60 * 60)(views.ArchivesView.as_view()), name='archives'),
- path('links.html', views.LinkListView.as_view(), name='links'),
- path(r'upload', views.fileupload, name='upload'),
- path(r'refresh', views.refresh_memcache, name='refresh')
-
-]
+ path(
+ r'',
+ views.IndexView.as_view(),
+ name='index'),
+ path(
+ r'page//',
+ views.IndexView.as_view(),
+ name='index_page'),
+ path(
+ r'article////.html',
+ views.ArticleDetailView.as_view(),
+ name='detailbyid'),
+ path(
+ r'category/.html',
+ views.CategoryDetailView.as_view(),
+ name='category_detail'),
+ path(
+ r'category//.html',
+ views.CategoryDetailView.as_view(),
+ name='category_detail_page'),
+ path(
+ r'author/.html',
+ views.AuthorDetailView.as_view(),
+ name='author_detail'),
+ path(
+ r'author//.html',
+ views.AuthorDetailView.as_view(),
+ name='author_detail_page'),
+ path(
+ r'tag/.html',
+ views.TagDetailView.as_view(),
+ name='tag_detail'),
+ path(
+ r'tag//.html',
+ views.TagDetailView.as_view(),
+ name='tag_detail_page'),
+ path(
+ 'archives.html',
+ cache_page(
+ 60 * 60)(
+ views.ArchivesView.as_view()),
+ name='archives'),
+ path(
+ 'links.html',
+ views.LinkListView.as_view(),
+ name='links'),
+ path(
+ r'upload',
+ views.fileupload,
+ name='upload'),
+ path(
+ r'refresh',
+ views.refresh_memcache,
+ name='refresh')]
diff --git a/blog/views.py b/blog/views.py
index adb225a..19f5275 100644
--- a/blog/views.py
+++ b/blog/views.py
@@ -38,7 +38,8 @@ class ArticleListView(ListView):
@property
def page_number(self):
page_kwarg = self.page_kwarg
- page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
+ page = self.kwargs.get(
+ page_kwarg) or self.request.GET.get(page_kwarg) or 1
return page
def get_queryset_cache_key(self):
@@ -131,7 +132,8 @@ class ArticleDetailView(DetailView):
kwargs['form'] = comment_form
kwargs['article_comments'] = article_comments
- kwargs['comment_count'] = len(article_comments) if article_comments else 0
+ kwargs['comment_count'] = len(
+ article_comments) if article_comments else 0
kwargs['next_article'] = self.object.next_article
kwargs['prev_article'] = self.object.prev_article
@@ -151,8 +153,10 @@ class CategoryDetailView(ArticleListView):
categoryname = category.name
self.categoryname = categoryname
- categorynames = list(map(lambda c: c.name, category.get_sub_categorys()))
- article_list = Article.objects.filter(category__name__in=categorynames, status='p')
+ categorynames = list(
+ map(lambda c: c.name, category.get_sub_categorys()))
+ article_list = Article.objects.filter(
+ category__name__in=categorynames, status='p')
return article_list
def get_queryset_cache_key(self):
@@ -160,7 +164,8 @@ class CategoryDetailView(ArticleListView):
category = get_object_or_404(Category, slug=slug)
categoryname = category.name
self.categoryname = categoryname
- cache_key = 'category_list_{categoryname}_{page}'.format(categoryname=categoryname, page=self.page_number)
+ cache_key = 'category_list_{categoryname}_{page}'.format(
+ categoryname=categoryname, page=self.page_number)
return cache_key
def get_context_data(self, **kwargs):
@@ -168,7 +173,7 @@ class CategoryDetailView(ArticleListView):
categoryname = self.categoryname
try:
categoryname = categoryname.split('/')[-1]
- except:
+ except BaseException:
pass
kwargs['page_type'] = CategoryDetailView.page_type
kwargs['tag_name'] = categoryname
@@ -183,12 +188,14 @@ class AuthorDetailView(ArticleListView):
def get_queryset_cache_key(self):
author_name = self.kwargs['author_name']
- cache_key = 'author_{author_name}_{page}'.format(author_name=author_name, page=self.page_number)
+ cache_key = 'author_{author_name}_{page}'.format(
+ author_name=author_name, page=self.page_number)
return cache_key
def get_queryset_data(self):
author_name = self.kwargs['author_name']
- article_list = Article.objects.filter(author__username=author_name, type='a', status='p')
+ article_list = Article.objects.filter(
+ author__username=author_name, type='a', status='p')
return article_list
def get_context_data(self, **kwargs):
@@ -209,7 +216,8 @@ class TagDetailView(ArticleListView):
tag = get_object_or_404(Tag, slug=slug)
tag_name = tag.name
self.name = tag_name
- article_list = Article.objects.filter(tags__name=tag_name, type='a', status='p')
+ article_list = Article.objects.filter(
+ tags__name=tag_name, type='a', status='p')
return article_list
def get_queryset_cache_key(self):
@@ -217,7 +225,8 @@ class TagDetailView(ArticleListView):
tag = get_object_or_404(Tag, slug=slug)
tag_name = tag.name
self.name = tag_name
- cache_key = 'tag_{tag_name}_{page}'.format(tag_name=tag_name, page=self.page_number)
+ cache_key = 'tag_{tag_name}_{page}'.format(
+ tag_name=tag_name, page=self.page_number)
return cache_key
def get_context_data(self, **kwargs):
@@ -274,8 +283,10 @@ def fileupload(request):
isimage = len([i for i in imgextensions if fname.find(i) >= 0]) > 0
blogsetting = get_blog_setting()
- basepath = r'{basedir}/{type}/{timestr}'.format(basedir=blogsetting.resource_path,
- type='files' if not isimage else 'image', timestr=timestr)
+ basepath = r'{basedir}/{type}/{timestr}'.format(
+ basedir=blogsetting.resource_path,
+ type='files' if not isimage else 'image',
+ timestr=timestr)
if settings.TESTING:
basepath = settings.BASE_DIR + '/uploads'
url = 'https://resource.lylinux.net/{type}/{timestr}/{filename}'.format(
@@ -313,21 +324,34 @@ def refresh_memcache(request):
return HttpResponse(e)
-def page_not_found_view(request, exception, template_name='blog/error_page.html'):
+def page_not_found_view(
+ request,
+ exception,
+ template_name='blog/error_page.html'):
if exception:
logger.error(exception)
url = request.get_full_path()
- return render(request, template_name,
- {'message': '哎呀,您访问的地址 ' + url + ' 是一个未知的地方。请点击首页看看别的?', 'statuscode': '404'}, status=404)
+ return render(request,
+ template_name,
+ {'message': '哎呀,您访问的地址 ' + url + ' 是一个未知的地方。请点击首页看看别的?',
+ 'statuscode': '404'},
+ status=404)
def server_error_view(request, template_name='blog/error_page.html'):
- return render(request, template_name,
- {'message': '哎呀,出错了,我已经收集到了错误信息,之后会抓紧抢修,请点击首页看看别的?', 'statuscode': '500'}, status=500)
+ return render(request,
+ template_name,
+ {'message': '哎呀,出错了,我已经收集到了错误信息,之后会抓紧抢修,请点击首页看看别的?',
+ 'statuscode': '500'},
+ status=500)
-def permission_denied_view(request, exception, template_name='blog/error_page.html'):
+def permission_denied_view(
+ request,
+ exception,
+ template_name='blog/error_page.html'):
if exception:
logger.error(exception)
- return render(request, template_name,
- {'message': '哎呀,您没有权限访问此页面,请点击首页看看别的?', 'statuscode': '403'}, status=403)
+ return render(
+ request, template_name, {
+ 'message': '哎呀,您没有权限访问此页面,请点击首页看看别的?', 'statuscode': '403'}, status=403)
diff --git a/comments/admin.py b/comments/admin.py
index b0cf3f4..79f024d 100644
--- a/comments/admin.py
+++ b/comments/admin.py
@@ -19,7 +19,13 @@ enable_commentstatus.short_description = '启用评论'
class CommentAdmin(admin.ModelAdmin):
list_per_page = 20
- list_display = ('id', 'body', 'link_to_userinfo', 'link_to_article', 'is_enable', 'created_time')
+ list_display = (
+ 'id',
+ 'body',
+ 'link_to_userinfo',
+ 'link_to_article',
+ 'is_enable',
+ 'created_time')
list_display_links = ('id', 'body')
list_filter = ('author', 'article', 'is_enable')
exclude = ('created_time', 'last_mod_time')
@@ -29,7 +35,8 @@ class CommentAdmin(admin.ModelAdmin):
info = (obj.author._meta.app_label, obj.author._meta.model_name)
link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,))
return format_html(
- u'%s' % (link, obj.author.nickname if obj.author.nickname else obj.author.email))
+ u'%s' %
+ (link, obj.author.nickname if obj.author.nickname else obj.author.email))
def link_to_article(self, obj):
info = (obj.author._meta.app_label, obj.author._meta.model_name)
diff --git a/comments/forms.py b/comments/forms.py
index 74751f1..ef8249e 100644
--- a/comments/forms.py
+++ b/comments/forms.py
@@ -22,11 +22,16 @@ from django.contrib.auth import get_user_model
class CommentForm(ModelForm):
url = forms.URLField(label='网址', required=False)
email = forms.EmailField(label='电子邮箱', required=True)
- name = forms.CharField(label='姓名', widget=forms.TextInput(attrs=
- {'value': "", 'size': "30", 'maxlength': "245",
- 'aria-required': 'true'}
- ))
- parent_comment_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
+ name = forms.CharField(
+ label='姓名',
+ widget=forms.TextInput(
+ attrs={
+ 'value': "",
+ 'size': "30",
+ 'maxlength': "245",
+ 'aria-required': 'true'}))
+ parent_comment_id = forms.IntegerField(
+ widget=forms.HiddenInput, required=False)
class Meta:
model = Comment
diff --git a/comments/models.py b/comments/models.py
index e825322..4ffb3c9 100644
--- a/comments/models.py
+++ b/comments/models.py
@@ -10,10 +10,22 @@ class Comment(models.Model):
body = models.TextField('正文', max_length=300)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
- author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者', on_delete=models.CASCADE)
- article = models.ForeignKey(Article, verbose_name='文章', on_delete=models.CASCADE)
- parent_comment = models.ForeignKey('self', verbose_name="上级评论", blank=True, null=True, on_delete=models.CASCADE)
- is_enable = models.BooleanField('是否显示', default=True, blank=False, null=False)
+ author = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ verbose_name='作者',
+ on_delete=models.CASCADE)
+ article = models.ForeignKey(
+ Article,
+ verbose_name='文章',
+ on_delete=models.CASCADE)
+ parent_comment = models.ForeignKey(
+ 'self',
+ verbose_name="上级评论",
+ blank=True,
+ null=True,
+ on_delete=models.CASCADE)
+ is_enable = models.BooleanField(
+ '是否显示', default=True, blank=False, null=False)
class Meta:
ordering = ['id']
diff --git a/comments/tests.py b/comments/tests.py
index baeee53..ff70206 100644
--- a/comments/tests.py
+++ b/comments/tests.py
@@ -18,8 +18,10 @@ class CommentsTest(TestCase):
def test_validate_comment(self):
site = get_current_site().domain
- user = BlogUser.objects.create_superuser(email="liangliangyy1@gmail.com",
- username="liangliangyy1", password="liangliangyy1")
+ user = BlogUser.objects.create_superuser(
+ email="liangliangyy1@gmail.com",
+ username="liangliangyy1",
+ password="liangliangyy1")
self.client.login(username='liangliangyy1', password='liangliangyy1')
@@ -38,7 +40,9 @@ class CommentsTest(TestCase):
article.status = 'p'
article.save()
- commenturl = reverse('comments:postcomment', kwargs={'article_id': article.id})
+ commenturl = reverse(
+ 'comments:postcomment', kwargs={
+ 'article_id': article.id})
response = self.client.post(commenturl,
{
@@ -66,17 +70,17 @@ class CommentsTest(TestCase):
response = self.client.post(commenturl,
{
'body': '''
- # Title1
-
+ # Title1
+
```python
import os
- ```
-
- [url](https://www.lylinux.net/)
-
- [ddd](http://www.baidu.com)
-
-
+ ```
+
+ [url](https://www.lylinux.net/)
+
+ [ddd](http://www.baidu.com)
+
+
''',
'email': user.email,
'name': user.username,
diff --git a/comments/urls.py b/comments/urls.py
index 0579ccc..79b9c83 100644
--- a/comments/urls.py
+++ b/comments/urls.py
@@ -19,5 +19,8 @@ from . import views
app_name = "comments"
urlpatterns = [
# url(r'^po456stcomment/(?P\d+)$', views.CommentPostView.as_view(), name='postcomment'),
- path('article//postcomment', views.CommentPostView.as_view(), name='postcomment'),
+ path(
+ 'article//postcomment',
+ views.CommentPostView.as_view(),
+ name='postcomment'),
]
diff --git a/comments/utils.py b/comments/utils.py
index 38375b0..353f372 100644
--- a/comments/utils.py
+++ b/comments/utils.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -23,7 +23,8 @@ logger = logging.getLogger(__name__)
def send_comment_email(comment):
site = get_current_site().domain
subject = '感谢您发表的评论'
- article_url = "https://{site}{path}".format(site=site, path=comment.article.get_absolute_url())
+ article_url = "https://{site}{path}".format(
+ site=site, path=comment.article.get_absolute_url())
html_content = """
非常感谢您在本站发表评论
您可以访问
diff --git a/comments/views.py b/comments/views.py
index 21b4955..1295175 100644
--- a/comments/views.py
+++ b/comments/views.py
@@ -50,7 +50,8 @@ class CommentPostView(FormView):
email = form.cleaned_data['email']
username = form.cleaned_data['name']
- user = get_user_model().objects.get_or_create(username=username, email=email)[0]
+ user = get_user_model().objects.get_or_create(
+ username=username, email=email)[0]
# auth.login(self.request, user)
comment = form.save(False)
comment.article = article
@@ -58,8 +59,11 @@ class CommentPostView(FormView):
comment.author = user
if form.cleaned_data['parent_comment_id']:
- parent_comment = Comment.objects.get(pk=form.cleaned_data['parent_comment_id'])
+ parent_comment = Comment.objects.get(
+ pk=form.cleaned_data['parent_comment_id'])
comment.parent_comment = parent_comment
comment.save(True)
- return HttpResponseRedirect("%s#div-comment-%d" % (article.get_absolute_url(), comment.pk))
+ return HttpResponseRedirect(
+ "%s#div-comment-%d" %
+ (article.get_absolute_url(), comment.pk))
diff --git a/docs/es.md b/docs/es.md
new file mode 100644
index 0000000..68ce49e
--- /dev/null
+++ b/docs/es.md
@@ -0,0 +1,28 @@
+# 集成Elasticsearch
+如果你已经有了`Elasticsearch`环境,那么可以将搜索从`Whoosh`换成`Elasticsearch`,集成方式也很简单,
+首先需要注意如下几点:
+1. 你的`Elasticsearch`支持`ik`中文分词
+2. 你的`Elasticsearch`版本>=7.3.0
+
+接下来在`settings.py`做如下改动即可:
+- 增加es链接,如下所示:
+```python
+ELASTICSEARCH_DSL = {
+ 'default': {
+ 'hosts': '127.0.0.1:9200'
+ },
+}
+```
+- 修改`HAYSTACK`配置:
+```python
+HAYSTACK_CONNECTIONS = {
+ 'default': {
+ 'ENGINE': 'DjangoBlog.elasticsearch_backend.ElasticSearchEngine',
+ },
+}
+```
+然后终端执行:
+```shell script
+./manage.py build_index
+```
+这将会在你的es中创建两个索引,分别是`blog`和`performance`,其中`blog`索引就是搜索所使用的,而`performance`会记录每个请求的响应时间,以供将来优化使用。
\ No newline at end of file
diff --git a/oauth/admin.py b/oauth/admin.py
index f778918..4708962 100644
--- a/oauth/admin.py
+++ b/oauth/admin.py
@@ -11,15 +11,22 @@ logger = logging.getLogger(__name__)
class OAuthUserAdmin(admin.ModelAdmin):
search_fields = ('nikename', 'email')
list_per_page = 20
- list_display = ('id', 'nikename', 'link_to_usermodel', 'show_user_image', 'type', 'email',)
+ list_display = (
+ 'id',
+ 'nikename',
+ 'link_to_usermodel',
+ 'show_user_image',
+ 'type',
+ 'email',
+ )
list_display_links = ('id', 'nikename')
list_filter = ('author', 'type',)
readonly_fields = []
def get_readonly_fields(self, request, obj=None):
return list(self.readonly_fields) + \
- [field.name for field in obj._meta.fields] + \
- [field.name for field in obj._meta.many_to_many]
+ [field.name for field in obj._meta.fields] + \
+ [field.name for field in obj._meta.many_to_many]
def has_add_permission(self, request):
return False
@@ -29,11 +36,14 @@ class OAuthUserAdmin(admin.ModelAdmin):
info = (obj.author._meta.app_label, obj.author._meta.model_name)
link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,))
return format_html(
- u'%s' % (link, obj.author.nickname if obj.author.nickname else obj.author.email))
+ u'%s' %
+ (link, obj.author.nickname if obj.author.nickname else obj.author.email))
def show_user_image(self, obj):
img = obj.picture
- return format_html(u'
' % (img))
+ return format_html(
+ u'
' %
+ (img))
link_to_usermodel.short_description = '用户'
show_user_image.short_description = '用户头像'
diff --git a/oauth/forms.py b/oauth/forms.py
index ccf8494..a64f9c8 100644
--- a/oauth/forms.py
+++ b/oauth/forms.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -23,4 +23,5 @@ class RequireEmailForm(forms.Form):
def __init__(self, *args, **kwargs):
super(RequireEmailForm, self).__init__(*args, **kwargs)
- self.fields['email'].widget = widgets.EmailInput(attrs={'placeholder': "email", "class": "form-control"})
+ self.fields['email'].widget = widgets.EmailInput(
+ attrs={'placeholder': "email", "class": "form-control"})
diff --git a/oauth/models.py b/oauth/models.py
index 66594bb..cbe73ff 100644
--- a/oauth/models.py
+++ b/oauth/models.py
@@ -8,8 +8,12 @@ from django.utils.translation import gettext_lazy as _
class OAuthUser(models.Model):
- author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='用户', blank=True, null=True,
- on_delete=models.CASCADE)
+ author = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ verbose_name='用户',
+ blank=True,
+ null=True,
+ on_delete=models.CASCADE)
openid = models.CharField(max_length=50)
nikename = models.CharField(max_length=50, verbose_name='昵称')
token = models.CharField(max_length=150, null=True, blank=True)
@@ -40,13 +44,20 @@ class OAuthConfig(models.Model):
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)
+ 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():
+ if OAuthConfig.objects.filter(
+ type=self.type).exclude(
+ id=self.id).count():
raise ValidationError(_(self.type + '已经存在'))
def __str__(self):
diff --git a/oauth/oauthmanager.py b/oauth/oauthmanager.py
index a0bb803..5d897ef 100644
--- a/oauth/oauthmanager.py
+++ b/oauth/oauthmanager.py
@@ -91,7 +91,11 @@ class WBOauthManager(BaseOauthManager):
self.client_id = config.appkey if config else ''
self.client_secret = config.appsecret if config else ''
self.callback_url = config.callback_url if config else ''
- super(WBOauthManager, self).__init__(access_token=access_token, openid=openid)
+ super(
+ WBOauthManager,
+ self).__init__(
+ access_token=access_token,
+ openid=openid)
def get_authorization_url(self, nexturl='/'):
params = {
@@ -158,7 +162,11 @@ class GoogleOauthManager(BaseOauthManager):
self.client_id = config.appkey if config else ''
self.client_secret = config.appsecret if config else ''
self.callback_url = config.callback_url if config else ''
- super(GoogleOauthManager, self).__init__(access_token=access_token, openid=openid)
+ super(
+ GoogleOauthManager,
+ self).__init__(
+ access_token=access_token,
+ openid=openid)
def get_authorization_url(self, nexturl='/'):
params = {
@@ -229,7 +237,11 @@ class GitHubOauthManager(BaseOauthManager):
self.client_id = config.appkey if config else ''
self.client_secret = config.appsecret if config else ''
self.callback_url = config.callback_url if config else ''
- super(GitHubOauthManager, self).__init__(access_token=access_token, openid=openid)
+ super(
+ GitHubOauthManager,
+ self).__init__(
+ access_token=access_token,
+ openid=openid)
def get_authorization_url(self, nexturl='/'):
params = {
@@ -295,7 +307,11 @@ class FaceBookOauthManager(BaseOauthManager):
self.client_id = config.appkey if config else ''
self.client_secret = config.appsecret if config else ''
self.callback_url = config.callback_url if config else ''
- super(FaceBookOauthManager, self).__init__(access_token=access_token, openid=openid)
+ super(
+ FaceBookOauthManager,
+ self).__init__(
+ access_token=access_token,
+ openid=openid)
def get_authorization_url(self, nexturl='/'):
params = {
@@ -362,7 +378,11 @@ class QQOauthManager(BaseOauthManager):
self.client_id = config.appkey if config else ''
self.client_secret = config.appsecret if config else ''
self.callback_url = config.callback_url if config else ''
- super(QQOauthManager, self).__init__(access_token=access_token, openid=openid)
+ super(
+ QQOauthManager,
+ self).__init__(
+ access_token=access_token,
+ openid=openid)
def get_authorization_url(self, nexturl='/'):
params = {
@@ -398,7 +418,10 @@ class QQOauthManager(BaseOauthManager):
}
rsp = self.do_get(self.OPEN_ID_URL, params)
if rsp:
- rsp = rsp.replace('callback(', '').replace(')', '').replace(';', '')
+ rsp = rsp.replace(
+ 'callback(', '').replace(
+ ')', '').replace(
+ ';', '')
obj = json.loads(rsp)
openid = str(obj['openid'])
self.openid = openid
@@ -442,7 +465,10 @@ def get_oauth_apps():
def get_manager_by_type(type):
applications = get_oauth_apps()
if applications:
- finds = list(filter(lambda x: x.ICON_NAME.lower() == type.lower(), applications))
+ finds = list(
+ filter(
+ lambda x: x.ICON_NAME.lower() == type.lower(),
+ applications))
if finds:
return finds[0]
return None
diff --git a/oauth/templatetags/__init__.py b/oauth/templatetags/__init__.py
index fd534e9..fa0f602 100644
--- a/oauth/templatetags/__init__.py
+++ b/oauth/templatetags/__init__.py
@@ -5,10 +5,10 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@file: __init__.py
@time: 2017/3/4 下午3:22
-"""
\ No newline at end of file
+"""
diff --git a/oauth/templatetags/oauth_tags.py b/oauth/templatetags/oauth_tags.py
index 8ab09d3..54067de 100644
--- a/oauth/templatetags/oauth_tags.py
+++ b/oauth/templatetags/oauth_tags.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -27,9 +27,8 @@ def load_oauth_applications(request):
baseurl = reverse('oauth:oauthlogin')
path = request.get_full_path()
- apps = list(map(lambda x: (x.ICON_NAME,
- '{baseurl}?type={type}&next_url={next}'
- .format(baseurl=baseurl, type=x.ICON_NAME, next=path)), applications))
+ apps = list(map(lambda x: (x.ICON_NAME, '{baseurl}?type={type}&next_url={next}' .format(
+ baseurl=baseurl, type=x.ICON_NAME, next=path)), applications))
else:
apps = []
return {
diff --git a/oauth/urls.py b/oauth/urls.py
index 9afa523..7820f60 100644
--- a/oauth/urls.py
+++ b/oauth/urls.py
@@ -19,9 +19,22 @@ from . import views
app_name = "oauth"
urlpatterns = [
- path(r'oauth/authorize', views.authorize),
- path(r'oauth/requireemail/.html', views.RequireEmailView.as_view(), name='require_email'),
- path(r'oauth/emailconfirm//.html', views.emailconfirm, name='email_confirm'),
- path(r'oauth/bindsuccess/.html', views.bindsuccess, name='bindsuccess'),
- path(r'oauth/oauthlogin', views.oauthlogin, name='oauthlogin')
-]
+ path(
+ r'oauth/authorize',
+ views.authorize),
+ path(
+ r'oauth/requireemail/.html',
+ views.RequireEmailView.as_view(),
+ name='require_email'),
+ path(
+ r'oauth/emailconfirm//.html',
+ views.emailconfirm,
+ name='email_confirm'),
+ path(
+ r'oauth/bindsuccess/.html',
+ views.bindsuccess,
+ name='bindsuccess'),
+ path(
+ r'oauth/oauthlogin',
+ views.oauthlogin,
+ name='oauthlogin')]
diff --git a/oauth/views.py b/oauth/views.py
index 720cd29..9ac49cd 100644
--- a/oauth/views.py
+++ b/oauth/views.py
@@ -104,7 +104,8 @@ def authorize(request):
user.author = author
user.save()
- oauth_user_login_signal.send(sender=authorize.__class__, id=user.id)
+ oauth_user_login_signal.send(
+ sender=authorize.__class__, id=user.id)
login(request, author)
return HttpResponseRedirect(nexturl)
else:
@@ -121,7 +122,10 @@ def authorize(request):
def emailconfirm(request, id, sign):
if not sign:
return HttpResponseForbidden()
- if not get_md5(settings.SECRET_KEY + str(id) + settings.SECRET_KEY).upper() == sign.upper():
+ if not get_md5(
+ settings.SECRET_KEY +
+ str(id) +
+ settings.SECRET_KEY).upper() == sign.upper():
return HttpResponseForbidden()
oauthuser = get_object_or_404(OAuthUser, pk=id)
with transaction.atomic():
@@ -132,12 +136,14 @@ def emailconfirm(request, id, sign):
author = result[0]
if result[1]:
author.source = 'emailconfirm'
- author.username = oauthuser.nikename.strip() if oauthuser.nikename.strip() else "djangoblog" + datetime.datetime.now().strftime(
- '%y%m%d%I%M%S')
+ author.username = oauthuser.nikename.strip() if oauthuser.nikename.strip(
+ ) else "djangoblog" + datetime.datetime.now().strftime('%y%m%d%I%M%S')
author.save()
oauthuser.author = author
oauthuser.save()
- oauth_user_login_signal.send(sender=emailconfirm.__class__, id=oauthuser.id)
+ oauth_user_login_signal.send(
+ sender=emailconfirm.__class__,
+ id=oauthuser.id)
login(request, author)
site = get_current_site().domain
@@ -193,7 +199,8 @@ class RequireEmailView(FormView):
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
oauthuser.email = email
oauthuser.save()
- sign = get_md5(settings.SECRET_KEY + str(oauthuser.id) + settings.SECRET_KEY)
+ sign = get_md5(settings.SECRET_KEY +
+ str(oauthuser.id) + settings.SECRET_KEY)
site = get_current_site().domain
if settings.DEBUG:
site = '127.0.0.1:8000'
@@ -229,7 +236,8 @@ def bindsuccess(request, oauthid):
content = "恭喜您,还差一步就绑定成功了,请登录您的邮箱查看邮件完成绑定,谢谢。"
else:
title = '绑定成功'
- content = "恭喜您绑定成功,您以后可以使用{type}来直接免密码登录本站啦,感谢您对本站对关注。".format(type=oauthuser.type)
+ content = "恭喜您绑定成功,您以后可以使用{type}来直接免密码登录本站啦,感谢您对本站对关注。".format(
+ type=oauthuser.type)
return render(request, 'oauth/bindsuccess.html', {
'title': title,
'content': content
diff --git a/owntracks/tests.py b/owntracks/tests.py
index b5c4950..2a679bc 100644
--- a/owntracks/tests.py
+++ b/owntracks/tests.py
@@ -19,7 +19,10 @@ class OwnTrackLogTest(TestCase):
'lon': 134.341
}
- self.client.post('/owntracks/logtracks', json.dumps(o), content_type='application/json')
+ self.client.post(
+ '/owntracks/logtracks',
+ json.dumps(o),
+ content_type='application/json')
length = len(OwnTrackLog.objects.all())
self.assertEqual(length, 1)
@@ -28,15 +31,20 @@ class OwnTrackLogTest(TestCase):
'lat': 123.123
}
- self.client.post('/owntracks/logtracks', json.dumps(o), content_type='application/json')
+ self.client.post(
+ '/owntracks/logtracks',
+ json.dumps(o),
+ content_type='application/json')
length = len(OwnTrackLog.objects.all())
self.assertEqual(length, 1)
rsp = self.client.get('/owntracks/show_maps')
self.assertEqual(rsp.status_code, 302)
- user = BlogUser.objects.create_superuser(email="liangliangyy1@gmail.com",
- username="liangliangyy1", password="liangliangyy1")
+ user = BlogUser.objects.create_superuser(
+ email="liangliangyy1@gmail.com",
+ username="liangliangyy1",
+ password="liangliangyy1")
self.client.login(username='liangliangyy1', password='liangliangyy1')
s = OwnTrackLog()
diff --git a/owntracks/urls.py b/owntracks/urls.py
index ee44cf5..7225c0a 100644
--- a/owntracks/urls.py
+++ b/owntracks/urls.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/owntracks/views.py b/owntracks/views.py
index 74f8285..e820c88 100644
--- a/owntracks/views.py
+++ b/owntracks/views.py
@@ -25,7 +25,9 @@ def manage_owntrack_log(request):
lat = s['lat']
lon = s['lon']
- logger.info('tid:{tid}.lat:{lat}.lon:{lon}'.format(tid=tid, lat=lat, lon=lon))
+ logger.info(
+ 'tid:{tid}.lat:{lat}.lon:{lon}'.format(
+ tid=tid, lat=lat, lon=lon))
if tid and lat and lon:
m = OwnTrackLog()
m.tid = tid
@@ -71,7 +73,8 @@ def convert_to_amap(locations):
item = list(itertools.islice(it, 30))
while item:
- datas = ';'.join(set(map(lambda x: str(x.lon) + ',' + str(x.lat), item)))
+ datas = ';'.join(
+ set(map(lambda x: str(x.lon) + ',' + str(x.lat), item)))
key = '8440a376dfc9743d8924bf0ad141f28e'
api = 'http://restapi.amap.com/v3/assistant/coordinate/convert'
@@ -94,20 +97,25 @@ def get_datas(request):
from django.utils.timezone import utc
now = django.utils.timezone.now().replace(tzinfo=utc)
- querydate = django.utils.timezone.datetime(now.year, now.month, now.day, 0, 0, 0)
+ querydate = django.utils.timezone.datetime(
+ now.year, now.month, now.day, 0, 0, 0)
if request.GET.get('date', None):
date = list(map(lambda x: int(x), request.GET.get('date').split('-')))
- querydate = django.utils.timezone.datetime(date[0], date[1], date[2], 0, 0, 0)
+ querydate = django.utils.timezone.datetime(
+ date[0], date[1], date[2], 0, 0, 0)
nextdate = querydate + datetime.timedelta(days=1)
- models = OwnTrackLog.objects.filter(created_time__range=(querydate, nextdate))
+ models = OwnTrackLog.objects.filter(
+ created_time__range=(querydate, nextdate))
result = list()
if models and len(models):
- for tid, item in groupby(sorted(models, key=lambda k: k.tid), key=lambda k: k.tid):
+ for tid, item in groupby(
+ sorted(models, key=lambda k: k.tid), key=lambda k: k.tid):
d = dict()
d["name"] = tid
paths = list()
- locations = convert_to_amap(sorted(item, key=lambda x: x.created_time))
+ locations = convert_to_amap(
+ sorted(item, key=lambda x: x.created_time))
for i in locations.split(';'):
paths.append(i.split(','))
d["path"] = paths
diff --git a/servermanager/Api/__init__.py b/servermanager/Api/__init__.py
index 667e57e..990c2c0 100644
--- a/servermanager/Api/__init__.py
+++ b/servermanager/Api/__init__.py
@@ -5,10 +5,10 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@file: __init__.py.py
@time: 2017/8/27 上午11:40
-"""
\ No newline at end of file
+"""
diff --git a/servermanager/Api/blogapi.py b/servermanager/Api/blogapi.py
index b1ba05b..24b3fea 100644
--- a/servermanager/Api/blogapi.py
+++ b/servermanager/Api/blogapi.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/servermanager/Api/commonapi.py b/servermanager/Api/commonapi.py
index bd55923..7669dde 100644
--- a/servermanager/Api/commonapi.py
+++ b/servermanager/Api/commonapi.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/servermanager/MemcacheStorage.py b/servermanager/MemcacheStorage.py
index e0e233a..d068814 100644
--- a/servermanager/MemcacheStorage.py
+++ b/servermanager/MemcacheStorage.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
diff --git a/servermanager/admin.py b/servermanager/admin.py
index 3233927..7897041 100644
--- a/servermanager/admin.py
+++ b/servermanager/admin.py
@@ -9,7 +9,12 @@ class CommandsAdmin(admin.ModelAdmin):
class EmailSendLogAdmin(admin.ModelAdmin):
list_display = ('title', 'emailto', 'send_result', 'created_time')
- readonly_fields = ('title', 'emailto', 'send_result', 'created_time', 'content')
+ readonly_fields = (
+ 'title',
+ 'emailto',
+ 'send_result',
+ 'created_time',
+ 'content')
def has_add_permission(self, request):
return False
diff --git a/servermanager/robot.py b/servermanager/robot.py
index fbee94c..75c1602 100644
--- a/servermanager/robot.py
+++ b/servermanager/robot.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm
@@ -26,7 +26,8 @@ from django.conf import settings
import jsonpickle
from servermanager.models import commands
-robot = WeRoBot(token=os.environ.get('DJANGO_WEROBOT_TOKEN') or 'lylinux', enable_session=True)
+robot = WeRoBot(token=os.environ.get('DJANGO_WEROBOT_TOKEN')
+ or 'lylinux', enable_session=True)
memstorage = MemcacheStorage()
if memstorage.is_available:
robot.config['SESSION_STORAGE'] = memstorage
@@ -114,12 +115,12 @@ def help(message, session):
'''
-@robot.filter(re.compile('^weather\:.*$', re.I))
+@robot.filter(re.compile(r'^weather\:.*$', re.I))
def weather(message, session):
return "建设中..."
-@robot.filter(re.compile('^idcard\:.*$', re.I))
+@robot.filter(re.compile(r'^idcard\:.*$', re.I))
def idcard(message, session):
return "建设中..."
@@ -135,7 +136,10 @@ class CommandHandler():
self.commands = commands.objects.all()
def run(self, title):
- cmd = list(filter(lambda x: x.title.upper() == title.upper(), self.commands))
+ cmd = list(
+ filter(
+ lambda x: x.title.upper() == title.upper(),
+ self.commands))
if cmd:
return self.__run_command__(cmd[0].command)
else:
@@ -145,7 +149,7 @@ class CommandHandler():
try:
str = os.popen(cmd).read()
return str
- except:
+ except BaseException:
return '命令执行出错!'
def get_help(self):
@@ -167,7 +171,7 @@ class MessageHandler():
try:
info = session[userid]
self.userinfo = jsonpickle.decode(info)
- except:
+ except BaseException:
userinfo = WxUserInfo()
self.userinfo = userinfo
@@ -197,7 +201,7 @@ class MessageHandler():
if self.userinfo.isAdmin and not self.userinfo.isPasswordSet:
passwd = settings.WXADMIN
if settings.TESTING:
- passwd='123'
+ passwd = '123'
if passwd.upper() == get_md5(get_md5(info)).upper():
self.userinfo.isPasswordSet = True
self.savesession()
diff --git a/servermanager/tests.py b/servermanager/tests.py
index 5932a1d..dd741bd 100644
--- a/servermanager/tests.py
+++ b/servermanager/tests.py
@@ -23,8 +23,10 @@ class ServerManagerTest(TestCase):
def test_validate_comment(self):
site = get_current_site().domain
- user = BlogUser.objects.create_superuser(email="liangliangyy1@gmail.com",
- username="liangliangyy1", password="liangliangyy1")
+ user = BlogUser.objects.create_superuser(
+ email="liangliangyy1@gmail.com",
+ username="liangliangyy1",
+ password="liangliangyy1")
self.client.login(username='liangliangyy1', password='liangliangyy1')
diff --git a/servermanager/urls.py b/servermanager/urls.py
index a5a075c..8600186 100644
--- a/servermanager/urls.py
+++ b/servermanager/urls.py
@@ -5,7 +5,7 @@
"""
@version: ??
@author: liangliangyy
-@license: MIT Licence
+@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.net/
@software: PyCharm