Compare commits
78 Commits
zjy_branch
...
yyb_branch
@ -1,2 +0,0 @@
|
||||
基于Python的Hello World
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,41 @@
|
||||
#yyb 导入必要的模块
|
||||
import logging
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
|
||||
#yyb 获取日志记录器
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SpiderNotify():
|
||||
"""#yyb 搜索引擎爬虫通知类"""
|
||||
|
||||
@staticmethod
|
||||
def baidu_notify(urls):
|
||||
"""
|
||||
#yyb 向百度站长平台提交链接,通知百度爬虫抓取更新内容
|
||||
|
||||
Args:
|
||||
urls: 需要通知的URL列表
|
||||
"""
|
||||
try:
|
||||
#yyb 将URL列表转换为换行分隔的字符串格式
|
||||
data = '\n'.join(urls)
|
||||
#yyb 向百度站长平台API提交URL数据
|
||||
result = requests.post(settings.BAIDU_NOTIFY_URL, data=data)
|
||||
#yyb 记录API返回结果
|
||||
logger.info(result.text)
|
||||
except Exception as e:
|
||||
#yyb 记录通知过程中的错误
|
||||
logger.error(e)
|
||||
|
||||
@staticmethod
|
||||
def notify(url):
|
||||
"""
|
||||
#yyb 通用的爬虫通知方法(目前仅支持百度)
|
||||
|
||||
Args:
|
||||
url: 需要通知的URL
|
||||
"""
|
||||
SpiderNotify.baidu_notify(url)
|
||||
@ -0,0 +1,44 @@
|
||||
#yyb 导入Django测试框架
|
||||
from django.test import TestCase
|
||||
|
||||
#yyb 导入工具函数
|
||||
from djangoblog.utils import *
|
||||
|
||||
|
||||
class DjangoBlogTest(TestCase):
|
||||
"""#yyb DjangoBlog应用测试类"""
|
||||
|
||||
def setUp(self):
|
||||
"""#yyb 测试初始化方法"""
|
||||
#yyb 可以在这里设置测试数据,当前为空
|
||||
pass
|
||||
|
||||
def test_utils(self):
|
||||
"""#yyb 测试工具函数"""
|
||||
#yyb 测试SHA256加密函数
|
||||
md5 = get_sha256('test')
|
||||
self.assertIsNotNone(md5) #yyb 断言加密结果不为空
|
||||
|
||||
#yyb 测试Markdown转换函数
|
||||
c = CommonMarkdown.get_markdown('''
|
||||
# Title1
|
||||
|
||||
```python
|
||||
import os
|
||||
```
|
||||
|
||||
[url](https://www.lylinux.net/)
|
||||
|
||||
[ddd](http://www.baidu.com)
|
||||
|
||||
|
||||
''')
|
||||
self.assertIsNotNone(c) #yyb 断言Markdown转换结果不为空
|
||||
|
||||
#yyb 测试字典转URL参数字符串函数
|
||||
d = {
|
||||
'd': 'key1',
|
||||
'd2': 'key2'
|
||||
}
|
||||
data = parse_dict_to_url(d)
|
||||
self.assertIsNotNone(data) #yyb 断言转换结果不为空
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,41 @@
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BasePlugin:
|
||||
# 插件元数据
|
||||
PLUGIN_NAME = None
|
||||
PLUGIN_DESCRIPTION = None
|
||||
PLUGIN_VERSION = None
|
||||
|
||||
def __init__(self):
|
||||
if not all([self.PLUGIN_NAME, self.PLUGIN_DESCRIPTION, self.PLUGIN_VERSION]):
|
||||
raise ValueError("Plugin metadata (PLUGIN_NAME, PLUGIN_DESCRIPTION, PLUGIN_VERSION) must be defined.")
|
||||
self.init_plugin()
|
||||
self.register_hooks()
|
||||
|
||||
def init_plugin(self):
|
||||
"""
|
||||
插件初始化逻辑
|
||||
子类可以重写此方法来实现特定的初始化操作
|
||||
"""
|
||||
logger.info(f'{self.PLUGIN_NAME} initialized.')
|
||||
|
||||
def register_hooks(self):
|
||||
"""
|
||||
注册插件钩子
|
||||
子类可以重写此方法来注册特定的钩子
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_plugin_info(self):
|
||||
"""
|
||||
获取插件信息
|
||||
:return: 包含插件元数据的字典
|
||||
"""
|
||||
return {
|
||||
'name': self.PLUGIN_NAME,
|
||||
'description': self.PLUGIN_DESCRIPTION,
|
||||
'version': self.PLUGIN_VERSION
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
ARTICLE_DETAIL_LOAD = 'article_detail_load'
|
||||
ARTICLE_CREATE = 'article_create'
|
||||
ARTICLE_UPDATE = 'article_update'
|
||||
ARTICLE_DELETE = 'article_delete'
|
||||
|
||||
ARTICLE_CONTENT_HOOK_NAME = "the_content"
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_hooks = {}
|
||||
|
||||
|
||||
def register(hook_name: str, callback: callable):
|
||||
"""
|
||||
注册一个钩子回调。
|
||||
"""
|
||||
if hook_name not in _hooks:
|
||||
_hooks[hook_name] = []
|
||||
_hooks[hook_name].append(callback)
|
||||
logger.debug(f"Registered hook '{hook_name}' with callback '{callback.__name__}'")
|
||||
|
||||
|
||||
def run_action(hook_name: str, *args, **kwargs):
|
||||
"""
|
||||
执行一个 Action Hook。
|
||||
它会按顺序执行所有注册到该钩子上的回调函数。
|
||||
"""
|
||||
if hook_name in _hooks:
|
||||
logger.debug(f"Running action hook '{hook_name}'")
|
||||
for callback in _hooks[hook_name]:
|
||||
try:
|
||||
callback(*args, **kwargs)
|
||||
except Exception as e:
|
||||
logger.error(f"Error running action hook '{hook_name}' callback '{callback.__name__}': {e}", exc_info=True)
|
||||
|
||||
|
||||
def apply_filters(hook_name: str, value, *args, **kwargs):
|
||||
"""
|
||||
执行一个 Filter Hook。
|
||||
它会把 value 依次传递给所有注册的回调函数进行处理。
|
||||
"""
|
||||
if hook_name in _hooks:
|
||||
logger.debug(f"Applying filter hook '{hook_name}'")
|
||||
for callback in _hooks[hook_name]:
|
||||
try:
|
||||
value = callback(value, *args, **kwargs)
|
||||
except Exception as e:
|
||||
logger.error(f"Error applying filter hook '{hook_name}' callback '{callback.__name__}': {e}", exc_info=True)
|
||||
return value
|
||||
@ -0,0 +1,19 @@
|
||||
import os
|
||||
import logging
|
||||
from django.conf import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def load_plugins():
|
||||
"""
|
||||
Dynamically loads and initializes plugins from the 'plugins' directory.
|
||||
This function is intended to be called when the Django app registry is ready.
|
||||
"""
|
||||
for plugin_name in settings.ACTIVE_PLUGINS:
|
||||
plugin_path = os.path.join(settings.PLUGINS_DIR, plugin_name)
|
||||
if os.path.isdir(plugin_path) and os.path.exists(os.path.join(plugin_path, 'plugin.py')):
|
||||
try:
|
||||
__import__(f'plugins.{plugin_name}.plugin')
|
||||
logger.info(f"Successfully loaded plugin: {plugin_name}")
|
||||
except ImportError as e:
|
||||
logger.error(f"Failed to import plugin: {plugin_name}", exc_info=e)
|
||||
@ -0,0 +1,41 @@
|
||||
#yyb 导入必要的模块
|
||||
import logging
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
|
||||
#yyb 获取日志记录器
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SpiderNotify():
|
||||
"""#yyb 搜索引擎爬虫通知类"""
|
||||
|
||||
@staticmethod
|
||||
def baidu_notify(urls):
|
||||
"""
|
||||
#yyb 向百度站长平台提交链接,通知百度爬虫抓取更新内容
|
||||
|
||||
Args:
|
||||
urls: 需要通知的URL列表
|
||||
"""
|
||||
try:
|
||||
#yyb 将URL列表转换为换行分隔的字符串格式
|
||||
data = '\n'.join(urls)
|
||||
#yyb 向百度站长平台API提交URL数据
|
||||
result = requests.post(settings.BAIDU_NOTIFY_URL, data=data)
|
||||
#yyb 记录API返回结果
|
||||
logger.info(result.text)
|
||||
except Exception as e:
|
||||
#yyb 记录通知过程中的错误
|
||||
logger.error(e)
|
||||
|
||||
@staticmethod
|
||||
def notify(url):
|
||||
"""
|
||||
#yyb 通用的爬虫通知方法(目前仅支持百度)
|
||||
|
||||
Args:
|
||||
url: 需要通知的URL
|
||||
"""
|
||||
SpiderNotify.baidu_notify(url)
|
||||
@ -0,0 +1,44 @@
|
||||
#yyb 导入Django测试框架
|
||||
from django.test import TestCase
|
||||
|
||||
#yyb 导入工具函数
|
||||
from djangoblog.utils import *
|
||||
|
||||
|
||||
class DjangoBlogTest(TestCase):
|
||||
"""#yyb DjangoBlog应用测试类"""
|
||||
|
||||
def setUp(self):
|
||||
"""#yyb 测试初始化方法"""
|
||||
#yyb 可以在这里设置测试数据,当前为空
|
||||
pass
|
||||
|
||||
def test_utils(self):
|
||||
"""#yyb 测试工具函数"""
|
||||
#yyb 测试SHA256加密函数
|
||||
md5 = get_sha256('test')
|
||||
self.assertIsNotNone(md5) #yyb 断言加密结果不为空
|
||||
|
||||
#yyb 测试Markdown转换函数
|
||||
c = CommonMarkdown.get_markdown('''
|
||||
# Title1
|
||||
|
||||
```python
|
||||
import os
|
||||
```
|
||||
|
||||
[url](https://www.lylinux.net/)
|
||||
|
||||
[ddd](http://www.baidu.com)
|
||||
|
||||
|
||||
''')
|
||||
self.assertIsNotNone(c) #yyb 断言Markdown转换结果不为空
|
||||
|
||||
#yyb 测试字典转URL参数字符串函数
|
||||
d = {
|
||||
'd': 'key1',
|
||||
'd2': 'key2'
|
||||
}
|
||||
data = parse_dict_to_url(d)
|
||||
self.assertIsNotNone(data) #yyb 断言转换结果不为空
|
||||
Loading…
Reference in new issue