Merge branch 'master' into modifycdn

This commit is contained in:
liangliang
2017-09-03 15:37:45 +08:00
21 changed files with 530 additions and 10 deletions
+2
View File
@@ -72,3 +72,5 @@ google93fd32dbd906620a.html
baidu_verify_FlHL7cUyC9.html
BingSiteAuth.xml
cb9339dbe2ff86a5aa169d28dba5f615.txt
werobot_session
+1
View File
@@ -1,3 +1,4 @@
dist: precise
language: python
python:
- "3.4"
+3 -1
View File
@@ -45,6 +45,7 @@ INSTALLED_APPS = [
'accounts',
'comments',
'oauth',
'servermanager',
'compressor'
]
@@ -234,7 +235,8 @@ DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER')
# 设置debug=false 未处理异常邮件通知
ADMINS = [('liangliang', 'liangliangyy@gmail.com')]
# 微信管理员密码(两次md5获得)
WXADMIN = '995F03AC401D6CABABAEF756FC4D43C7'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
+1 -1
View File
@@ -41,6 +41,6 @@ urlpatterns = [
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
url(r'^feed/$', DjangoBlogFeed()),
url(r'^search', include('haystack.urls'), name='search'),
url(r'', include('servermanager.urls', namespace='servermanager', app_name='servermanagers'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+2 -1
View File
@@ -45,7 +45,8 @@ windows电脑:
为了安全起见,没有把`SECRET_KEY`上传到Github中而是在环境变量中配置的,如果你想要正常运行的话,需要修改`settings.py`中的`SECRET_KEY`为你自己的就可以了。
如:
`SECRET_KEY = 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'`
`SECRET_KEY = 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'`
若本地部署后发现静态文件无法加载.请将`settings.py`中的`DEBUG=False`修改为`DEBUG=True`即可.
## 运行
+6 -3
View File
@@ -2,13 +2,14 @@ appdirs==1.4.3
Django==1.11.4
django-appconf==1.0.2
django-autoslug==1.9.3
django-compressor==2.1.1
django-compressor==2.2
django-debug-toolbar==1.8
django-haystack==2.6.1
django-ipware==1.1.6
django-pagedown==0.1.3
django-uuslug==1.1.8
jieba==0.38
jieba==0.39
jsonpickle==0.9.5
markdown2==2.3.4
mistune==0.7.4
olefile==0.44
@@ -21,10 +22,12 @@ python-memcached==1.58
python-slugify==1.2.4
pytz==2017.2
rcssmin==1.0.6
requests==2.18.3
requests==2.18.4
rjsmin==1.0.12
six==1.10.0
sqlparse==0.2.3
Unidecode==0.4.21
urllib3==1.22
webencodings==0.5.1
WeRoBot==1.1.1
Whoosh==2.7.4
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: __init__.py.py
@time: 2017/8/27 上午11:40
"""
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: blogapi.py
@time: 2017/8/27 上午11:40
"""
from blog.models import Article, Category, Tag
from haystack.query import EmptySearchQuerySet, SearchQuerySet
class BlogApi():
def __init__(self):
self.searchqueryset = SearchQuerySet()
self.searchqueryset.auto_query('')
self.__max_takecount__ = 8
def search_articles(self, query):
sqs = self.searchqueryset.auto_query(query)
sqs = sqs.load_all()
return sqs[:self.__max_takecount__]
def get_category_lists(self):
return Category.objects.all()
def get_category_articles(self, categoryname):
articles = Article.objects.filter(category__name=categoryname)
if articles:
return articles[:self.__max_takecount__]
return None
def get_recent_articles(self):
return Article.objects.all()[:self.__max_takecount__]
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: commonapi.py
@time: 2017/9/2 上午1:43
"""
import requests
import json
from DjangoBlog.utils import logger
class TuLing():
def __init__(self):
self.__key__ = '2f1446eb0321804291b0a1e217c25bb5'
self.__appid__ = 137762
def __build_req_url(self, content):
return 'http://www.tuling123.com/openapi/api?key=%s&info=%s&userid=%s' % (
self.__key__, content, self.__appid__)
def UserAgent(self, url):
rsp = requests.get(url)
return rsp.content
def getdata(self, content):
requrl = self.__build_req_url(content)
res = self.UserAgent(requrl)
try:
jsons = json.loads(res, encoding='utf-8')
if str(jsons["code"]) == '100000':
return jsons["text"]
except Exception as e:
print(e)
logger.warn(e)
return "哎呀,出错啦。"
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: MemcacheStorage.py
@time: 2017/8/27 上午2:42
"""
from werobot.session import SessionStorage
from werobot.utils import json_loads, json_dumps
from DjangoBlog.utils import cache
class MemcacheStorage(SessionStorage):
def __init__(self, prefix='ws_'):
self.prefix = prefix
self.cache = cache
@property
def is_available(self):
value = "1"
self.set('checkavaliable', value=value)
return value == self.get('checkavaliable')
def key_name(self, s):
return '{prefix}{s}'.format(prefix=self.prefix, s=s)
def get(self, id):
id = self.key_name(id)
session_json = self.cache.get(id) or '{}'
return json_loads(session_json)
def set(self, id, value):
id = self.key_name(id)
self.cache.set(id, json_dumps(value))
def delete(self, id):
id = self.key_name(id)
self.cache.delete(id)
View File
+11
View File
@@ -0,0 +1,11 @@
from django.contrib import admin
# Register your models here.
from .models import commands
class CommandsAdmin(admin.ModelAdmin):
pass
admin.site.register(commands, CommandsAdmin)
+5
View File
@@ -0,0 +1,5 @@
from django.apps import AppConfig
class ServermanagerConfig(AppConfig):
name = 'servermanager'
+17
View File
@@ -0,0 +1,17 @@
from django.db import models
# Create your models here.
class commands(models.Model):
title = models.CharField('命令标题', max_length=300)
command = models.CharField('命令', max_length=2000)
describe = models.CharField('命令描述', max_length=300)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
last_mod_time = models.DateTimeField('修改时间', auto_now=True)
def __str__(self):
return self.title
class Meta:
verbose_name = '命令'
verbose_name_plural = verbose_name
+239
View File
@@ -0,0 +1,239 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: robot.py
@time: 2017/8/27 上午1:55
"""
from werobot import WeRoBot
import re
from werobot.replies import ArticlesReply, MusicReply, ImageReply, Article
from .MemcacheStorage import MemcacheStorage
from servermanager.Api.blogapi import BlogApi
from servermanager.Api.commonapi import TuLing
import os
import json
from DjangoBlog.utils import get_md5
from django.conf import settings
import jsonpickle
from servermanager.models import commands
robot = WeRoBot(token='lylinux', enable_session=True)
memstorage = MemcacheStorage()
if memstorage.is_available:
robot.config['SESSION_STORAGE'] = memstorage
else:
from werobot.session.filestorage import FileStorage
robot.config['SESSION_STORAGE'] = FileStorage(filename='werobot_session')
blogapi = BlogApi()
tuling = TuLing()
def convert_to_articlereply(articles, message):
reply = ArticlesReply(message=message)
from blog.templatetags.blog_tags import custom_markdown, truncatechars_content
from DjangoBlog.utils import CommonMarkdown
from django.utils.safestring import mark_safe
for post in articles:
imgs = re.findall(r'(?:http\:|https\:)?\/\/.*\.(?:png|jpg)', post.body)
imgurl = ''
if imgs:
imgurl = imgs[0]
article = Article(
title=post.title,
description=truncatechars_content(post.body),
img=imgurl,
url=post.get_full_url()
)
reply.add_article(article)
return reply
@robot.filter(re.compile(r"^\?.*"))
def search(message, session):
s = message.content
searchstr = str(s).replace('?', '')
result = blogapi.search_articles(searchstr)
if result:
articles = list(map(lambda x: x.object, result))
reply = convert_to_articlereply(articles, message)
return reply
else:
return '没有找到相关文章。'
@robot.filter(re.compile(r'^category\s*$', re.I))
def category(message, session):
categorys = blogapi.get_category_lists()
content = ','.join(map(lambda x: x.name, categorys))
return '所有文章分类目录:' + content
@robot.filter(re.compile(r'^recent\s*$', re.I))
def recents(message, session):
articles = blogapi.get_recent_articles()
if articles:
reply = convert_to_articlereply(articles, message)
return reply
else:
return "暂时还没有文章"
@robot.filter(re.compile('^help$', re.I))
def help(message, session):
return '''欢迎关注!
默认会与图灵机器人聊天~~
你可以通过下面这些命令来获得信息
?关键字搜索文章.
如?python.
category获得文章分类目录及文章数.
category-***获得该分类目录文章
如category-python
recent获得最新文章
help获得帮助.
weather:获得天气
如weather:西安
idcard:获得身份证信息
如idcard:61048119xxxxxxxxxx
music:音乐搜索
如music:阴天快乐
PS:以上标点符号都不支持中文标点~~
'''
@robot.filter(re.compile('^weather\:.*$', re.I))
def weather(message, session):
return "建设中..."
@robot.filter(re.compile('^idcard\:.*$', re.I))
def idcard(message, session):
return "建设中..."
@robot.handler
def echo(message, session):
handler = MessageHandler(message, session)
return handler.handler()
class CommandHandler():
def __init__(self):
self.commands = commands.objects.all()
def run(self, title):
cmd = list(filter(lambda x: x.title.upper() == title.upper(), self.commands))
if cmd:
return self.__run_command__(cmd[0].command)
else:
return "未找到相关命令,请输入hepme获得帮助。"
def __run_command__(self, cmd):
try:
str = os.popen(cmd).read()
return str
except:
return '命令执行出错!'
def get_help(self):
rsp = ''
for cmd in self.commands:
rsp += '{c}:{d}\n'.format(c=cmd.command, d=cmd.describe)
return rsp
cmdhandler = CommandHandler()
class MessageHandler():
def __init__(self, message, session):
userid = message.source
self.message = message
self.session = session
self.userid = userid
try:
info = session[userid]
self.userinfo = jsonpickle.decode(info)
except:
userinfo = WxUserInfo()
self.userinfo = userinfo
@property
def is_admin(self):
return self.userinfo.isAdmin
@property
def is_password_set(self):
return self.userinfo.isPasswordSet
def savesession(self):
info = jsonpickle.encode(self.userinfo)
self.session[self.userid] = info
def handler(self):
info = self.message.content
if self.userinfo.isAdmin and info.upper() == 'EXIT':
self.userinfo = WxUserInfo()
self.savesession()
return "退出成功"
if info.upper() == 'ADMIN':
self.userinfo.isAdmin = True
self.savesession()
return "输入管理员密码"
if self.userinfo.isAdmin and not self.userinfo.isPasswordSet:
passwd = settings.WXADMIN
if passwd.upper() == get_md5(get_md5(info)).upper():
self.userinfo.isPasswordSet = True
self.savesession()
return "验证通过,请输入命令或者要执行的命令代码:输入helpme获得帮助"
else:
if self.userinfo.Count >= 3:
self.userinfo = WxUserInfo()
self.savesession()
return "超过验证次数"
self.userinfo.Count += 1
self.savesession()
return "验证失败,请重新输入管理员密码:"
if self.userinfo.isAdmin and self.userinfo.isPasswordSet:
if self.userinfo.Command != '' and info.upper() == 'Y':
return cmdhandler.run(self.userinfo.Command)
else:
if info.upper() == 'HELPME':
return cmdhandler.get_help()
self.userinfo.Command = info
self.savesession()
return "确认执行: " + info + " 命令?"
rsp = tuling.getdata(info)
return rsp
class WxUserInfo():
def __init__(self):
self.isAdmin = False
self.isPasswordSet = False
self.Count = 0
self.Command = ''
"""
@robot.handler
def hello(message, session):
blogapi = BlogApi()
result = blogapi.search_articles(message.content)
if result:
articles = list(map(lambda x: x.object, result))
reply = convert_to_articlereply(articles, message)
return reply
else:
return '没有找到相关文章。'
"""
+66
View File
@@ -0,0 +1,66 @@
from django.test import Client, RequestFactory, TestCase
from django.contrib.sites.models import Site
from .models import commands
import datetime
from accounts.models import BlogUser
from blog.models import Category, Article
from .robot import search, category, recents
from werobot.messages.messages import TextMessage
from .robot import MessageHandler, CommandHandler
# Create your tests here.
class ServerManagerTest(TestCase):
def setUp(self):
self.client = Client()
self.factory = RequestFactory()
def test_validate_comment(self):
site = Site.objects.get_current().domain
user = BlogUser.objects.create_superuser(email="liangliangyy1@gmail.com",
username="liangliangyy1", password="liangliangyy1")
self.client.login(username='liangliangyy1', password='liangliangyy1')
c = Category()
c.name = "categoryccc"
c.created_time = datetime.datetime.now()
c.last_mod_time = datetime.datetime.now()
c.save()
article = Article()
article.title = "nicetitleccc"
article.body = "nicecontentccc"
article.author = user
article.category = c
article.type = 'a'
article.status = 'p'
article.save()
s = TextMessage([])
s.content = "nicetitleccc"
rsp = search(s, None)
self.assertTrue(rsp != '没有找到相关文章。')
rsp = category(None, None)
self.assertIsNotNone(rsp)
rsp = recents(None, None)
self.assertTrue(rsp != '暂时还没有文章')
cmd = commands()
cmd.title = "test"
cmd.command = "ls"
cmd.describe = "test"
cmd.save()
cmdhandler = CommandHandler()
rsp = cmdhandler.run('test')
self.assertIsNotNone(rsp)
s.source = 'u'
s.content = 'test'
msghandler = MessageHandler(s, {})
d = msghandler.is_admin
e = msghandler.is_password_set
msghandler.userinfo.isPasswordSet = True
msghandler.userinfo.isAdmin = True
msghandler.handler()
s.content = 'y'
msghandler.handler()
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@version: ??
@author: liangliangyy
@license: MIT Licence
@contact: liangliangyy@gmail.com
@site: https://www.lylinux.org/
@software: PyCharm
@file: urls.py
@time: 2017/8/27 上午2:27
"""
from django.conf.urls import url
from werobot.contrib.django import make_view
from .robot import robot
urlpatterns = [
url(r'^robot/', make_view(robot)),
]
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+6 -3
View File
@@ -2,13 +2,14 @@ appdirs==1.4.3
Django==1.11.4
django-appconf==1.0.2
django-autoslug==1.9.3
django-compressor==2.1.1
django-compressor==2.2
django-debug-toolbar==1.8
django-haystack==2.6.1
django-ipware==1.1.6
django-pagedown==0.1.3
django-uuslug==1.1.8
jieba==0.38
jieba==0.39
jsonpickle==0.9.5
markdown2==2.3.4
mistune==0.7.4
olefile==0.44
@@ -20,10 +21,12 @@ pyparsing==2.2.0
python-slugify==1.2.4
pytz==2017.2
rcssmin==1.0.6
requests==2.18.3
requests==2.18.4
rjsmin==1.0.12
six==1.10.0
sqlparse==0.2.3
Unidecode==0.4.21
urllib3==1.22
webencodings==0.5.1
WeRoBot==1.1.1
Whoosh==2.7.4
+3 -1
View File
@@ -47,6 +47,7 @@ INSTALLED_APPS = [
'accounts',
'comments',
'oauth',
'servermanager',
'compressor'
]
@@ -235,7 +236,8 @@ DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER')
# 设置debug=false 未处理异常邮件通知
ADMINS = [('liangliang', 'liangliangyy@gmail.com')]
# 微信管理员密码(两次md5获得)
WXADMIN = '995F03AC401D6CABABAEF756FC4D43C7'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,