From 6188b19134d6f005224e1fef66c14ae4a5aff897 Mon Sep 17 00:00:00 2001 From: pwe53ixz6 <1765557195@qq.com> Date: Sun, 21 Sep 2025 18:10:07 +0800 Subject: [PATCH 01/14] ADD file via upload --- github | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 github diff --git a/github b/github new file mode 100644 index 0000000..e69de29 From 1c2f60f3675198bdf73eb49a64083f3c60c2206e Mon Sep 17 00:00:00 2001 From: pwe53ixz6 <1765557195@qq.com> Date: Sun, 21 Sep 2025 18:16:38 +0800 Subject: [PATCH 02/14] Add .github --- .github | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github diff --git a/.github b/.github new file mode 100644 index 0000000..66dc905 --- /dev/null +++ b/.github @@ -0,0 +1 @@ +undefined \ No newline at end of file From a70efd4ae7826861e7050576de3d5caa9897c01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=98=95=E5=84=92?= Date: Tue, 23 Sep 2025 22:32:06 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test.txt/1.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test.txt/1.txt diff --git a/test.txt/1.txt b/test.txt/1.txt new file mode 100644 index 0000000..e69de29 From e5cd1d760b509ad5a0908f322eb438447c746547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=8E=B9?= <1765557195@qq.com> Date: Wed, 24 Sep 2025 09:29:19 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20my=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 测试.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 测试.txt diff --git a/测试.txt b/测试.txt new file mode 100644 index 0000000..e69de29 From 792ea01c5fa25d69390d3e0a8279d05a2cfc9ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=8E=B9?= <1765557195@qq.com> Date: Wed, 24 Sep 2025 10:19:40 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20wxr=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wxr.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 wxr.txt diff --git a/wxr.txt b/wxr.txt new file mode 100644 index 0000000..e69de29 From 7bda1cf077d6506ec250680b622870b5f73f4c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=8E=B9?= <1765557195@qq.com> Date: Wed, 24 Sep 2025 10:38:44 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20develop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .coveragerc | 10 + .dockerignore | 11 + .gitattributes | 6 + .github | 1 - .github/ISSUE_TEMPLATE.md | 18 + .github/workflows/codeql-analysis.yml | 47 + .github/workflows/django.yml | 136 +++ .github/workflows/docker.yml | 43 + .github/workflows/publish-release.yml | 39 + .gitignore | 80 ++ Dockerfile | 15 + LICENSE | 20 + README.md | 156 +++ accounts/__init__.py | 0 accounts/admin.py | 59 + accounts/apps.py | 5 + accounts/forms.py | 117 ++ accounts/migrations/0001_initial.py | 49 + ...s_remove_bloguser_created_time_and_more.py | 46 + accounts/migrations/__init__.py | 0 accounts/models.py | 35 + accounts/templatetags/__init__.py | 0 accounts/tests.py | 207 ++++ accounts/urls.py | 28 + accounts/user_login_backend.py | 26 + accounts/utils.py | 49 + accounts/views.py | 204 ++++ blog/__init__.py | 0 blog/admin.py | 112 ++ blog/apps.py | 5 + blog/context_processors.py | 43 + blog/documents.py | 213 ++++ blog/forms.py | 19 + blog/management/__init__.py | 0 blog/management/commands/__init__.py | 0 blog/management/commands/build_index.py | 18 + .../management/commands/build_search_words.py | 13 + blog/management/commands/clear_cache.py | 11 + blog/management/commands/create_testdata.py | 40 + blog/management/commands/ping_baidu.py | 50 + blog/management/commands/sync_user_avatar.py | 47 + blog/middleware.py | 42 + blog/migrations/0001_initial.py | 137 +++ ...002_blogsettings_global_footer_and_more.py | 23 + .../0003_blogsettings_comment_need_review.py | 17 + ...de_blogsettings_analytics_code_and_more.py | 27 + ...options_alter_category_options_and_more.py | 300 +++++ .../0006_alter_blogsettings_options.py | 17 + blog/migrations/__init__.py | 0 blog/models.py | 376 ++++++ blog/search_indexes.py | 13 + blog/templatetags/__init__.py | 0 blog/templatetags/blog_tags.py | 344 ++++++ blog/tests.py | 232 ++++ blog/urls.py | 62 + blog/views.py | 379 ++++++ comments/__init__.py | 0 comments/admin.py | 47 + comments/apps.py | 5 + comments/forms.py | 13 + comments/migrations/0001_initial.py | 38 + .../0002_alter_comment_is_enable.py | 18 + ...ns_remove_comment_created_time_and_more.py | 60 + comments/migrations/__init__.py | 0 comments/models.py | 39 + comments/templatetags/__init__.py | 0 comments/templatetags/comments_tags.py | 30 + comments/tests.py | 109 ++ comments/urls.py | 11 + comments/utils.py | 38 + comments/views.py | 63 + deploy/docker-compose/docker-compose.es.yml | 48 + deploy/docker-compose/docker-compose.yml | 60 + deploy/entrypoint.sh | 31 + deploy/k8s/configmap.yaml | 119 ++ deploy/k8s/deployment.yaml | 274 +++++ deploy/k8s/gateway.yaml | 17 + deploy/k8s/pv.yaml | 94 ++ deploy/k8s/pvc.yaml | 60 + deploy/k8s/service.yaml | 80 ++ deploy/k8s/storageclass.yaml | 10 + deploy/nginx.conf | 50 + djangoblog/__init__.py | 1 + djangoblog/admin_site.py | 64 + djangoblog/apps.py | 11 + djangoblog/blog_signals.py | 122 ++ djangoblog/elasticsearch_backend.py | 183 +++ djangoblog/feeds.py | 40 + djangoblog/logentryadmin.py | 91 ++ djangoblog/plugin_manage/base_plugin.py | 41 + djangoblog/plugin_manage/hook_constants.py | 7 + djangoblog/plugin_manage/hooks.py | 44 + djangoblog/plugin_manage/loader.py | 19 + djangoblog/settings.py | 343 ++++++ djangoblog/sitemap.py | 59 + djangoblog/spider_notify.py | 21 + djangoblog/tests.py | 32 + djangoblog/urls.py | 64 + djangoblog/utils.py | 232 ++++ djangoblog/whoosh_cn_backend.py | 1044 +++++++++++++++++ djangoblog/wsgi.py | 16 + docs/README-en.md | 158 +++ docs/config-en.md | 64 + docs/config.md | 58 + docs/docker-en.md | 114 ++ docs/docker.md | 114 ++ docs/es.md | 28 + docs/imgs/alipay.jpg | Bin 0 -> 17961 bytes docs/imgs/pycharm_logo.png | Bin 0 -> 132045 bytes docs/imgs/wechat.jpg | Bin 0 -> 24722 bytes docs/k8s-en.md | 141 +++ docs/k8s.md | 141 +++ locale/en/LC_MESSAGES/django.mo | Bin 0 -> 11097 bytes locale/en/LC_MESSAGES/django.po | 685 +++++++++++ locale/zh_Hans/LC_MESSAGES/django.mo | Bin 0 -> 10321 bytes locale/zh_Hans/LC_MESSAGES/django.po | 667 +++++++++++ locale/zh_Hant/LC_MESSAGES/django.mo | Bin 0 -> 10268 bytes locale/zh_Hant/LC_MESSAGES/django.po | 668 +++++++++++ manage.py | 22 + oauth/__init__.py | 0 oauth/admin.py | 54 + oauth/apps.py | 5 + oauth/forms.py | 12 + oauth/migrations/0001_initial.py | 57 + ...ptions_alter_oauthuser_options_and_more.py | 86 ++ .../0003_alter_oauthuser_nickname.py | 18 + oauth/migrations/__init__.py | 0 oauth/models.py | 67 ++ oauth/oauthmanager.py | 504 ++++++++ oauth/templatetags/__init__.py | 1 + oauth/templatetags/oauth_tags.py | 22 + oauth/tests.py | 249 ++++ oauth/urls.py | 25 + oauth/views.py | 253 ++++ owntracks/__init__.py | 0 owntracks/admin.py | 7 + owntracks/apps.py | 5 + owntracks/migrations/0001_initial.py | 31 + ...0002_alter_owntracklog_options_and_more.py | 22 + owntracks/migrations/__init__.py | 0 owntracks/models.py | 20 + owntracks/tests.py | 64 + owntracks/urls.py | 12 + owntracks/views.py | 127 ++ plugins/__init__.py | 1 + plugins/article_copyright/__init__.py | 1 + plugins/article_copyright/plugin.py | 32 + plugins/external_links/__init__.py | 1 + plugins/external_links/plugin.py | 48 + plugins/reading_time/__init__.py | 1 + plugins/reading_time/plugin.py | 43 + plugins/seo_optimizer/__init__.py | 1 + plugins/seo_optimizer/plugin.py | 142 +++ plugins/view_count/__init__.py | 1 + plugins/view_count/plugin.py | 18 + requirements.txt | Bin 0 -> 2554 bytes servermanager/MemcacheStorage.py | 32 + servermanager/__init__.py | 0 servermanager/admin.py | 19 + servermanager/api/__init__.py | 1 + servermanager/api/blogapi.py | 27 + servermanager/api/commonapi.py | 64 + servermanager/apps.py | 5 + servermanager/migrations/0001_initial.py | 45 + ...002_alter_emailsendlog_options_and_more.py | 32 + servermanager/migrations/__init__.py | 0 servermanager/models.py | 33 + servermanager/robot.py | 187 +++ servermanager/tests.py | 79 ++ servermanager/urls.py | 10 + servermanager/views.py | 1 + templates/account/forget_password.html | 30 + templates/account/login.html | 46 + templates/account/registration_form.html | 29 + templates/account/result.html | 27 + templates/blog/article_archives.html | 60 + templates/blog/article_detail.html | 52 + templates/blog/article_index.html | 42 + templates/blog/error_page.html | 45 + templates/blog/links_list.html | 44 + templates/blog/tags/article_info.html | 74 ++ templates/blog/tags/article_meta_info.html | 59 + templates/blog/tags/article_pagination.html | 17 + templates/blog/tags/article_tag_list.html | 19 + templates/blog/tags/breadcrumb.html | 19 + templates/blog/tags/sidebar.html | 136 +++ templates/comments/tags/comment_item.html | 34 + .../comments/tags/comment_item_tree.html | 54 + templates/comments/tags/comment_list.html | 45 + templates/comments/tags/post_comment.html | 33 + templates/oauth/bindsuccess.html | 22 + templates/oauth/oauth_applications.html | 13 + templates/oauth/require_email.html | 46 + templates/owntracks/show_log_dates.html | 17 + templates/owntracks/show_maps.html | 135 +++ .../search/indexes/blog/article_text.txt | 3 + templates/search/search.html | 66 ++ templates/share_layout/adsense.html | 6 + templates/share_layout/base.html | 123 ++ templates/share_layout/base_account.html | 47 + templates/share_layout/footer.html | 56 + templates/share_layout/nav.html | 30 + templates/share_layout/nav_node.html | 19 + 203 files changed, 14467 insertions(+), 1 deletion(-) create mode 100644 .coveragerc create mode 100644 .dockerignore create mode 100644 .gitattributes delete mode 100644 .github create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/django.yml create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/publish-release.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 accounts/__init__.py create mode 100644 accounts/admin.py create mode 100644 accounts/apps.py create mode 100644 accounts/forms.py create mode 100644 accounts/migrations/0001_initial.py create mode 100644 accounts/migrations/0002_alter_bloguser_options_remove_bloguser_created_time_and_more.py create mode 100644 accounts/migrations/__init__.py create mode 100644 accounts/models.py create mode 100644 accounts/templatetags/__init__.py create mode 100644 accounts/tests.py create mode 100644 accounts/urls.py create mode 100644 accounts/user_login_backend.py create mode 100644 accounts/utils.py create mode 100644 accounts/views.py create mode 100644 blog/__init__.py create mode 100644 blog/admin.py create mode 100644 blog/apps.py create mode 100644 blog/context_processors.py create mode 100644 blog/documents.py create mode 100644 blog/forms.py create mode 100644 blog/management/__init__.py create mode 100644 blog/management/commands/__init__.py create mode 100644 blog/management/commands/build_index.py create mode 100644 blog/management/commands/build_search_words.py create mode 100644 blog/management/commands/clear_cache.py create mode 100644 blog/management/commands/create_testdata.py create mode 100644 blog/management/commands/ping_baidu.py create mode 100644 blog/management/commands/sync_user_avatar.py create mode 100644 blog/middleware.py create mode 100644 blog/migrations/0001_initial.py create mode 100644 blog/migrations/0002_blogsettings_global_footer_and_more.py create mode 100644 blog/migrations/0003_blogsettings_comment_need_review.py create mode 100644 blog/migrations/0004_rename_analyticscode_blogsettings_analytics_code_and_more.py create mode 100644 blog/migrations/0005_alter_article_options_alter_category_options_and_more.py create mode 100644 blog/migrations/0006_alter_blogsettings_options.py create mode 100644 blog/migrations/__init__.py create mode 100644 blog/models.py create mode 100644 blog/search_indexes.py create mode 100644 blog/templatetags/__init__.py create mode 100644 blog/templatetags/blog_tags.py create mode 100644 blog/tests.py create mode 100644 blog/urls.py create mode 100644 blog/views.py create mode 100644 comments/__init__.py create mode 100644 comments/admin.py create mode 100644 comments/apps.py create mode 100644 comments/forms.py create mode 100644 comments/migrations/0001_initial.py create mode 100644 comments/migrations/0002_alter_comment_is_enable.py create mode 100644 comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py create mode 100644 comments/migrations/__init__.py create mode 100644 comments/models.py create mode 100644 comments/templatetags/__init__.py create mode 100644 comments/templatetags/comments_tags.py create mode 100644 comments/tests.py create mode 100644 comments/urls.py create mode 100644 comments/utils.py create mode 100644 comments/views.py create mode 100644 deploy/docker-compose/docker-compose.es.yml create mode 100644 deploy/docker-compose/docker-compose.yml create mode 100644 deploy/entrypoint.sh create mode 100644 deploy/k8s/configmap.yaml create mode 100644 deploy/k8s/deployment.yaml create mode 100644 deploy/k8s/gateway.yaml create mode 100644 deploy/k8s/pv.yaml create mode 100644 deploy/k8s/pvc.yaml create mode 100644 deploy/k8s/service.yaml create mode 100644 deploy/k8s/storageclass.yaml create mode 100644 deploy/nginx.conf create mode 100644 djangoblog/__init__.py create mode 100644 djangoblog/admin_site.py create mode 100644 djangoblog/apps.py create mode 100644 djangoblog/blog_signals.py create mode 100644 djangoblog/elasticsearch_backend.py create mode 100644 djangoblog/feeds.py create mode 100644 djangoblog/logentryadmin.py create mode 100644 djangoblog/plugin_manage/base_plugin.py create mode 100644 djangoblog/plugin_manage/hook_constants.py create mode 100644 djangoblog/plugin_manage/hooks.py create mode 100644 djangoblog/plugin_manage/loader.py create mode 100644 djangoblog/settings.py create mode 100644 djangoblog/sitemap.py create mode 100644 djangoblog/spider_notify.py create mode 100644 djangoblog/tests.py create mode 100644 djangoblog/urls.py create mode 100644 djangoblog/utils.py create mode 100644 djangoblog/whoosh_cn_backend.py create mode 100644 djangoblog/wsgi.py create mode 100644 docs/README-en.md create mode 100644 docs/config-en.md create mode 100644 docs/config.md create mode 100644 docs/docker-en.md create mode 100644 docs/docker.md create mode 100644 docs/es.md create mode 100644 docs/imgs/alipay.jpg create mode 100644 docs/imgs/pycharm_logo.png create mode 100644 docs/imgs/wechat.jpg create mode 100644 docs/k8s-en.md create mode 100644 docs/k8s.md create mode 100644 locale/en/LC_MESSAGES/django.mo create mode 100644 locale/en/LC_MESSAGES/django.po create mode 100644 locale/zh_Hans/LC_MESSAGES/django.mo create mode 100644 locale/zh_Hans/LC_MESSAGES/django.po create mode 100644 locale/zh_Hant/LC_MESSAGES/django.mo create mode 100644 locale/zh_Hant/LC_MESSAGES/django.po create mode 100644 manage.py create mode 100644 oauth/__init__.py create mode 100644 oauth/admin.py create mode 100644 oauth/apps.py create mode 100644 oauth/forms.py create mode 100644 oauth/migrations/0001_initial.py create mode 100644 oauth/migrations/0002_alter_oauthconfig_options_alter_oauthuser_options_and_more.py create mode 100644 oauth/migrations/0003_alter_oauthuser_nickname.py create mode 100644 oauth/migrations/__init__.py create mode 100644 oauth/models.py create mode 100644 oauth/oauthmanager.py create mode 100644 oauth/templatetags/__init__.py create mode 100644 oauth/templatetags/oauth_tags.py create mode 100644 oauth/tests.py create mode 100644 oauth/urls.py create mode 100644 oauth/views.py create mode 100644 owntracks/__init__.py create mode 100644 owntracks/admin.py create mode 100644 owntracks/apps.py create mode 100644 owntracks/migrations/0001_initial.py create mode 100644 owntracks/migrations/0002_alter_owntracklog_options_and_more.py create mode 100644 owntracks/migrations/__init__.py create mode 100644 owntracks/models.py create mode 100644 owntracks/tests.py create mode 100644 owntracks/urls.py create mode 100644 owntracks/views.py create mode 100644 plugins/__init__.py create mode 100644 plugins/article_copyright/__init__.py create mode 100644 plugins/article_copyright/plugin.py create mode 100644 plugins/external_links/__init__.py create mode 100644 plugins/external_links/plugin.py create mode 100644 plugins/reading_time/__init__.py create mode 100644 plugins/reading_time/plugin.py create mode 100644 plugins/seo_optimizer/__init__.py create mode 100644 plugins/seo_optimizer/plugin.py create mode 100644 plugins/view_count/__init__.py create mode 100644 plugins/view_count/plugin.py create mode 100644 requirements.txt create mode 100644 servermanager/MemcacheStorage.py create mode 100644 servermanager/__init__.py create mode 100644 servermanager/admin.py create mode 100644 servermanager/api/__init__.py create mode 100644 servermanager/api/blogapi.py create mode 100644 servermanager/api/commonapi.py create mode 100644 servermanager/apps.py create mode 100644 servermanager/migrations/0001_initial.py create mode 100644 servermanager/migrations/0002_alter_emailsendlog_options_and_more.py create mode 100644 servermanager/migrations/__init__.py create mode 100644 servermanager/models.py create mode 100644 servermanager/robot.py create mode 100644 servermanager/tests.py create mode 100644 servermanager/urls.py create mode 100644 servermanager/views.py create mode 100644 templates/account/forget_password.html create mode 100644 templates/account/login.html create mode 100644 templates/account/registration_form.html create mode 100644 templates/account/result.html create mode 100644 templates/blog/article_archives.html create mode 100644 templates/blog/article_detail.html create mode 100644 templates/blog/article_index.html create mode 100644 templates/blog/error_page.html create mode 100644 templates/blog/links_list.html create mode 100644 templates/blog/tags/article_info.html create mode 100644 templates/blog/tags/article_meta_info.html create mode 100644 templates/blog/tags/article_pagination.html create mode 100644 templates/blog/tags/article_tag_list.html create mode 100644 templates/blog/tags/breadcrumb.html create mode 100644 templates/blog/tags/sidebar.html create mode 100644 templates/comments/tags/comment_item.html create mode 100644 templates/comments/tags/comment_item_tree.html create mode 100644 templates/comments/tags/comment_list.html create mode 100644 templates/comments/tags/post_comment.html create mode 100644 templates/oauth/bindsuccess.html create mode 100644 templates/oauth/oauth_applications.html create mode 100644 templates/oauth/require_email.html create mode 100644 templates/owntracks/show_log_dates.html create mode 100644 templates/owntracks/show_maps.html create mode 100644 templates/search/indexes/blog/article_text.txt create mode 100644 templates/search/search.html create mode 100644 templates/share_layout/adsense.html create mode 100644 templates/share_layout/base.html create mode 100644 templates/share_layout/base_account.html create mode 100644 templates/share_layout/footer.html create mode 100644 templates/share_layout/nav.html create mode 100644 templates/share_layout/nav_node.html diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..9757484 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,10 @@ +[run] +source = . +include = *.py +omit = + *migrations* + *tests* + *.html + *whoosh_cn_backend* + *settings.py* + *venv* diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2818c38 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +bin/data/ +# virtualenv +venv/ +collectedstatic/ +djangoblog/whoosh_index/ +uploads/ +settings_production.py +*.md +docs/ +logs/ +static/ \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fd52ece --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +blog/static/* linguist-vendored +*.js linguist-vendored +*.css linguist-vendored +* text=auto +*.sh text eol=lf +*.conf text eol=lf \ No newline at end of file diff --git a/.github b/.github deleted file mode 100644 index 66dc905..0000000 --- a/.github +++ /dev/null @@ -1 +0,0 @@ -undefined \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..2b5b7aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,18 @@ + + +**我确定我已经查看了** (标注`[ ]`为`[x]`) + +- [ ] [DjangoBlog的readme](https://github.com/liangliangyy/DjangoBlog/blob/master/README.md) +- [ ] [配置说明](https://github.com/liangliangyy/DjangoBlog/blob/master/bin/config.md) +- [ ] [其他 Issues](https://github.com/liangliangyy/DjangoBlog/issues) + +---- + +**我要申请** (标注`[ ]`为`[x]`) + +- [ ] BUG 反馈 +- [ ] 添加新的特性或者功能 +- [ ] 请求技术支持 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..6b76522 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,47 @@ +name: "CodeQL" + +on: + push: + branches: + - master + - dev + paths-ignore: + - '**/*.md' + - '**/*.css' + - '**/*.js' + - '**/*.yml' + - '**/*.txt' + pull_request: + branches: + - master + - dev + paths-ignore: + - '**/*.md' + - '**/*.css' + - '**/*.js' + - '**/*.yml' + - '**/*.txt' + schedule: + - cron: '30 1 * * 0' + + +jobs: + CodeQL-Build: + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml new file mode 100644 index 0000000..94baea9 --- /dev/null +++ b/.github/workflows/django.yml @@ -0,0 +1,136 @@ +name: Django CI + +on: + push: + branches: + - master + - dev + paths-ignore: + - '**/*.md' + - '**/*.css' + - '**/*.js' + pull_request: + branches: + - master + - dev + paths-ignore: + - '**/*.md' + - '**/*.css' + - '**/*.js' + +jobs: + build-normal: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: ["3.10","3.11" ] + + steps: + - name: Start MySQL + uses: samin/mysql-action@v1.3 + with: + host port: 3306 + container port: 3306 + character set server: utf8mb4 + collation server: utf8mb4_general_ci + mysql version: latest + mysql root password: root + mysql database: djangoblog + mysql user: root + mysql password: root + + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run Tests + env: + DJANGO_MYSQL_PASSWORD: root + DJANGO_MYSQL_HOST: 127.0.0.1 + run: | + python manage.py makemigrations + python manage.py migrate + python manage.py test + + build-with-es: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: ["3.10","3.11" ] + + steps: + - name: Start MySQL + uses: samin/mysql-action@v1.3 + with: + host port: 3306 + container port: 3306 + character set server: utf8mb4 + collation server: utf8mb4_general_ci + mysql version: latest + mysql root password: root + mysql database: djangoblog + mysql user: root + mysql password: root + + - name: Configure sysctl limits + run: | + sudo swapoff -a + sudo sysctl -w vm.swappiness=1 + sudo sysctl -w fs.file-max=262144 + sudo sysctl -w vm.max_map_count=262144 + + - uses: miyataka/elasticsearch-github-actions@1 + + with: + stack-version: '7.12.1' + plugins: 'https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-7.12.1.zip' + + + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run Tests + env: + DJANGO_MYSQL_PASSWORD: root + DJANGO_MYSQL_HOST: 127.0.0.1 + DJANGO_ELASTICSEARCH_HOST: 127.0.0.1:9200 + run: | + python manage.py makemigrations + python manage.py migrate + coverage run manage.py test + coverage xml + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + push: false + tags: djangoblog/djangoblog:dev diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..a312e2f --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,43 @@ +name: docker + +on: + push: + paths-ignore: + - '**/*.md' + - '**/*.yml' + branches: + - 'master' + - 'dev' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set env to docker dev tag + if: endsWith(github.ref, '/dev') + run: | + echo "DOCKER_TAG=test" >> $GITHUB_ENV + - name: Set env to docker latest tag + if: endsWith(github.ref, '/master') + run: | + echo "DOCKER_TAG=latest" >> $GITHUB_ENV + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/djangoblog:${{env.DOCKER_TAG}} + + diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000..5eb0853 --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,39 @@ +name: publish release + +on: + release: + types: [ published ] + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: name/app + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + push: true + platforms: | + linux/amd64 + linux/arm64 + linux/arm/v7 + linux/arm/v6 + linux/386 + tags: ${{ secrets.DOCKERHUB_USERNAME }}/djangoblog:${{ github.event.release.tag_name }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3015816 --- /dev/null +++ b/.gitignore @@ -0,0 +1,80 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.pot + +# Django stuff: +*.log +logs/ + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + + +# PyCharm +# http://www.jetbrains.com/pycharm/webhelp/project.html +.idea +.iml +static/ +# virtualenv +venv/ + +collectedstatic/ +djangoblog/whoosh_index/ +google93fd32dbd906620a.html +baidu_verify_FlHL7cUyC9.html +BingSiteAuth.xml +cb9339dbe2ff86a5aa169d28dba5f615.txt +werobot_session.* +django.jpg +uploads/ +settings_production.py +werobot_session.db +bin/datas/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..80b46ac --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.11 +ENV PYTHONUNBUFFERED 1 +WORKDIR /code/djangoblog/ +RUN apt-get update && \ + apt-get install default-libmysqlclient-dev gettext -y && \ + rm -rf /var/lib/apt/lists/* +ADD requirements.txt requirements.txt +RUN pip install --upgrade pip && \ + pip install --no-cache-dir -r requirements.txt && \ + pip install --no-cache-dir gunicorn[gevent] && \ + pip cache purge + +ADD . . +RUN chmod +x /code/djangoblog/deploy/entrypoint.sh +ENTRYPOINT ["/code/djangoblog/deploy/entrypoint.sh"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3b08474 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2025 车亮亮 + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index e713206..56aa4cc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,158 @@ # DjangoBlog +

+ Django CI + CodeQL + codecov + license +

+ +

+ 一款功能强大、设计优雅的现代化博客系统 +
+ English简体中文 +

+ +--- + +DjangoBlog 是一款基于 Python 3.10 和 Django 4.0 构建的高性能博客平台。它不仅提供了传统博客的所有核心功能,还通过一个灵活的插件系统,让您可以轻松扩展和定制您的网站。无论您是个人博主、技术爱好者还是内容创作者,DjangoBlog 都旨在为您提供一个稳定、高效且易于维护的写作和发布环境。 + +## ✨ 特性亮点 + +- **强大的内容管理**: 支持文章、独立页面、分类和标签的完整管理。内置强大的 Markdown 编辑器,支持代码语法高亮。 +- **全文搜索**: 集成搜索引擎,提供快速、精准的文章内容搜索。 +- **互动评论系统**: 支持回复、邮件提醒等功能,评论内容同样支持 Markdown。 +- **灵活的侧边栏**: 可自定义展示最新文章、最多阅读、标签云等模块。 +- **社交化登录**: 内置 OAuth 支持,已集成 Google, GitHub, Facebook, 微博, QQ 等主流平台。 +- **高性能缓存**: 原生支持 Redis 缓存,并提供自动刷新机制,确保网站高速响应。 +- **SEO 友好**: 具备基础 SEO 功能,新内容发布后可自动通知 Google 和百度。 +- **便捷的插件系统**: 通过创建独立的插件来扩展博客功能,代码解耦,易于维护。我们已经通过插件实现了文章浏览计数、SEO 优化等功能! +- **集成图床**: 内置简单的图床功能,方便图片上传和管理。 +- **自动化前端**: 集成 `django-compressor`,自动压缩和优化 CSS 及 JavaScript 文件。 +- **健壮的运维**: 内置网站异常邮件提醒和微信公众号管理功能。 + +## 🛠️ 技术栈 + +- **后端**: Python 3.10, Django 4.0 +- **数据库**: MySQL, SQLite (可配置) +- **缓存**: Redis +- **前端**: HTML5, CSS3, JavaScript +- **搜索**: Whoosh, Elasticsearch (可配置) +- **编辑器**: Markdown (mdeditor) + +## 🚀 快速开始 + +### 1. 环境准备 + +确保您的系统中已安装 Python 3.10+ 和 MySQL/MariaDB。 + +### 2. 克隆与安装 + +```bash +# 克隆项目到本地 +git clone https://github.com/liangliangyy/DjangoBlog.git +cd DjangoBlog + +# 安装依赖 +pip install -r requirements.txt +``` + +### 3. 项目配置 + +- **数据库**: + 打开 `djangoblog/settings.py` 文件,找到 `DATABASES` 配置项,修改为您的 MySQL 连接信息。 + + ```python + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'djangoblog', + 'USER': 'root', + 'PASSWORD': 'your_password', + 'HOST': '127.0.0.1', + 'PORT': 3306, + } + } + ``` + 在 MySQL 中创建数据库: + ```sql + CREATE DATABASE `djangoblog` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + ``` + +- **更多配置**: + 关于邮件发送、OAuth 登录、缓存等更多高级配置,请参阅我们的 [详细配置文档](/docs/config.md)。 + +### 4. 初始化数据库 + +```bash +python manage.py makemigrations +python manage.py migrate + +# 创建一个超级管理员账户 +python manage.py createsuperuser +``` + +### 5. 运行项目 + +```bash +# (可选) 生成一些测试数据 +python manage.py create_testdata + +# (可选) 收集和压缩静态文件 +python manage.py collectstatic --noinput +python manage.py compress --force + +# 启动开发服务器 +python manage.py runserver +``` + +现在,在您的浏览器中访问 `http://127.0.0.1:8000/`,您应该能看到 DjangoBlog 的首页了! + +## 部署 + +- **传统部署**: 我们为您准备了非常详细的 [服务器部署教程](https://www.lylinux.net/article/2019/8/5/58.html)。 +- **Docker 部署**: 项目已全面支持 Docker。如果您熟悉容器化技术,请参考 [Docker 部署文档](/docs/docker.md) 来快速启动。 +- **Kubernetes 部署**: 我们也提供了完整的 [Kubernetes 部署指南](/docs/k8s.md),助您轻松上云。 + +## 🧩 插件系统 + +插件系统是 DjangoBlog 的核心特色之一。它允许您在不修改核心代码的情况下,通过编写独立的插件来为您的博客添加新功能。 + +- **工作原理**: 插件通过在预定义的“钩子”上注册回调函数来工作。例如,当一篇文章被渲染时,`after_article_body_get` 钩子会被触发,所有注册到此钩子的函数都会被执行。 +- **现有插件**: `view_count`(浏览计数), `seo_optimizer`(SEO优化)等都是通过插件系统实现的。 +- **开发您自己的插件**: 只需在 `plugins` 目录下创建一个新的文件夹,并编写您的 `plugin.py`。欢迎探索并为 DjangoBlog 社区贡献您的创意! + +## 🤝 贡献指南 + +我们热烈欢迎任何形式的贡献!如果您有好的想法或发现了 Bug,请随时提交 Issue 或 Pull Request。 + +## 📄 许可证 + +本项目基于 [MIT License](LICENSE) 开源。 + +--- + +## ❤️ 支持与赞助 + +如果您觉得这个项目对您有帮助,并且希望支持我继续维护和开发新功能,欢迎请我喝杯咖啡!您的每一份支持都是我前进的最大动力。 + +

+ 支付宝赞助 + 微信赞助 +

+

+ (左) 支付宝 / (右) 微信 +

+ +## 🙏 鸣谢 + +特别感谢 **JetBrains** 为本项目提供的免费开源许可证。 + +

+ + JetBrains Logo + +

+ +--- +> 如果本项目帮助到了你,请在[这里](https://github.com/liangliangyy/DjangoBlog/issues/214)留下你的网址,让更多的人看到。您的回复将会是我继续更新维护下去的动力。 diff --git a/accounts/__init__.py b/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/admin.py b/accounts/admin.py new file mode 100644 index 0000000..32e483c --- /dev/null +++ b/accounts/admin.py @@ -0,0 +1,59 @@ +from django import forms +from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.forms import UserChangeForm +from django.contrib.auth.forms import UsernameField +from django.utils.translation import gettext_lazy as _ + +# Register your models here. +from .models import BlogUser + + +class BlogUserCreationForm(forms.ModelForm): + password1 = forms.CharField(label=_('password'), widget=forms.PasswordInput) + password2 = forms.CharField(label=_('Enter password again'), widget=forms.PasswordInput) + + class Meta: + model = BlogUser + fields = ('email',) + + def clean_password2(self): + # Check that the two password entries match + password1 = self.cleaned_data.get("password1") + password2 = self.cleaned_data.get("password2") + if password1 and password2 and password1 != password2: + raise forms.ValidationError(_("passwords do not match")) + return password2 + + def save(self, commit=True): + # Save the provided password in hashed format + user = super().save(commit=False) + user.set_password(self.cleaned_data["password1"]) + if commit: + user.source = 'adminsite' + user.save() + return user + + +class BlogUserChangeForm(UserChangeForm): + class Meta: + model = BlogUser + fields = '__all__' + field_classes = {'username': UsernameField} + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + +class BlogUserAdmin(UserAdmin): + form = BlogUserChangeForm + add_form = BlogUserCreationForm + list_display = ( + 'id', + 'nickname', + 'username', + 'email', + 'last_login', + 'date_joined', + 'source') + list_display_links = ('id', 'username') + ordering = ('-id',) diff --git a/accounts/apps.py b/accounts/apps.py new file mode 100644 index 0000000..9b3fc5a --- /dev/null +++ b/accounts/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + name = 'accounts' diff --git a/accounts/forms.py b/accounts/forms.py new file mode 100644 index 0000000..fce4137 --- /dev/null +++ b/accounts/forms.py @@ -0,0 +1,117 @@ +from django import forms +from django.contrib.auth import get_user_model, password_validation +from django.contrib.auth.forms import AuthenticationForm, UserCreationForm +from django.core.exceptions import ValidationError +from django.forms import widgets +from django.utils.translation import gettext_lazy as _ +from . import utils +from .models import BlogUser + + +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['password'].widget = widgets.PasswordInput( + attrs={'placeholder': "password", "class": "form-control"}) + + +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['password1'].widget = widgets.PasswordInput( + attrs={'placeholder': "password", "class": "form-control"}) + self.fields['password2'].widget = widgets.PasswordInput( + attrs={'placeholder': "repeat password", "class": "form-control"}) + + def clean_email(self): + email = self.cleaned_data['email'] + if get_user_model().objects.filter(email=email).exists(): + raise ValidationError(_("email already exists")) + return email + + class Meta: + model = get_user_model() + fields = ("username", "email") + + +class ForgetPasswordForm(forms.Form): + new_password1 = forms.CharField( + label=_("New password"), + widget=forms.PasswordInput( + attrs={ + "class": "form-control", + 'placeholder': _("New password") + } + ), + ) + + new_password2 = forms.CharField( + label="确认密码", + widget=forms.PasswordInput( + attrs={ + "class": "form-control", + 'placeholder': _("Confirm password") + } + ), + ) + + email = forms.EmailField( + label='邮箱', + widget=forms.TextInput( + attrs={ + 'class': 'form-control', + 'placeholder': _("Email") + } + ), + ) + + code = forms.CharField( + label=_('Code'), + widget=forms.TextInput( + attrs={ + 'class': 'form-control', + 'placeholder': _("Code") + } + ), + ) + + def clean_new_password2(self): + password1 = self.data.get("new_password1") + password2 = self.data.get("new_password2") + if password1 and password2 and password1 != password2: + raise ValidationError(_("passwords do not match")) + password_validation.validate_password(password2) + + return password2 + + def clean_email(self): + user_email = self.cleaned_data.get("email") + if not BlogUser.objects.filter( + email=user_email + ).exists(): + # todo 这里的报错提示可以判断一个邮箱是不是注册过,如果不想暴露可以修改 + raise ValidationError(_("email does not exist")) + return user_email + + def clean_code(self): + code = self.cleaned_data.get("code") + error = utils.verify( + email=self.cleaned_data.get("email"), + code=code, + ) + if error: + raise ValidationError(error) + return code + + +class ForgetPasswordCodeForm(forms.Form): + email = forms.EmailField( + label=_('Email'), + ) diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..d2fbcab --- /dev/null +++ b/accounts/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +import django.contrib.auth.models +import django.contrib.auth.validators +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='BlogUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('nickname', models.CharField(blank=True, max_length=100, verbose_name='昵称')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('source', models.CharField(blank=True, max_length=100, verbose_name='创建来源')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': '用户', + 'verbose_name_plural': '用户', + 'ordering': ['-id'], + 'get_latest_by': 'id', + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/accounts/migrations/0002_alter_bloguser_options_remove_bloguser_created_time_and_more.py b/accounts/migrations/0002_alter_bloguser_options_remove_bloguser_created_time_and_more.py new file mode 100644 index 0000000..1a9f509 --- /dev/null +++ b/accounts/migrations/0002_alter_bloguser_options_remove_bloguser_created_time_and_more.py @@ -0,0 +1,46 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:13 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='bloguser', + options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'user', 'verbose_name_plural': 'user'}, + ), + migrations.RemoveField( + model_name='bloguser', + name='created_time', + ), + migrations.RemoveField( + model_name='bloguser', + name='last_mod_time', + ), + migrations.AddField( + model_name='bloguser', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='bloguser', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'), + ), + migrations.AlterField( + model_name='bloguser', + name='nickname', + field=models.CharField(blank=True, max_length=100, verbose_name='nick name'), + ), + migrations.AlterField( + model_name='bloguser', + name='source', + field=models.CharField(blank=True, max_length=100, verbose_name='create source'), + ), + ] diff --git a/accounts/migrations/__init__.py b/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/models.py b/accounts/models.py new file mode 100644 index 0000000..3baddbb --- /dev/null +++ b/accounts/models.py @@ -0,0 +1,35 @@ +from django.contrib.auth.models import AbstractUser +from django.db import models +from django.urls import reverse +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ +from djangoblog.utils import get_current_site + + +# Create your models here. + +class BlogUser(AbstractUser): + nickname = models.CharField(_('nick name'), max_length=100, blank=True) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_modify_time = models.DateTimeField(_('last modify time'), default=now) + source = models.CharField(_('create source'), max_length=100, blank=True) + + def get_absolute_url(self): + 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()) + return url + + class Meta: + ordering = ['-id'] + verbose_name = _('user') + verbose_name_plural = verbose_name + get_latest_by = 'id' diff --git a/accounts/templatetags/__init__.py b/accounts/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/tests.py b/accounts/tests.py new file mode 100644 index 0000000..6893411 --- /dev/null +++ b/accounts/tests.py @@ -0,0 +1,207 @@ +from django.test import Client, RequestFactory, TestCase +from django.urls import reverse +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + +from accounts.models import BlogUser +from blog.models import Article, Category +from djangoblog.utils import * +from . import utils + + +# Create your tests here. + +class AccountTest(TestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + self.blog_user = BlogUser.objects.create_user( + username="test", + email="admin@admin.com", + password="12345678" + ) + self.new_test = "xxx123--=" + + def test_validate_account(self): + site = get_current_site().domain + 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') + self.assertEqual(loginresult, True) + response = self.client.get('/admin/') + self.assertEqual(response.status_code, 200) + + category = Category() + category.name = "categoryaaa" + category.creation_time = timezone.now() + category.last_modify_time = timezone.now() + category.save() + + article = Article() + article.title = "nicetitleaaa" + article.body = "nicecontentaaa" + article.author = user + article.category = category + article.type = 'a' + article.status = 'p' + article.save() + + response = self.client.get(article.get_admin_url()) + self.assertEqual(response.status_code, 200) + + def test_validate_register(self): + 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'))) + user = BlogUser.objects.filter(email='user123@user.com')[0] + sign = get_sha256(get_sha256(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) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + self.client.login(username='user1233', password='password123!q@wE#R$T') + user = BlogUser.objects.filter(email='user123@user.com')[0] + user.is_superuser = True + user.is_staff = True + user.save() + delete_sidebar_cache() + category = Category() + category.name = "categoryaaa" + category.creation_time = timezone.now() + category.last_modify_time = timezone.now() + category.save() + + article = Article() + article.category = category + article.title = "nicetitle333" + article.body = "nicecontentttt" + article.author = user + + article.type = 'a' + article.status = 'p' + article.save() + + response = self.client.get(article.get_admin_url()) + self.assertEqual(response.status_code, 200) + + response = self.client.get(reverse('account:logout')) + self.assertIn(response.status_code, [301, 302, 200]) + + response = self.client.get(article.get_admin_url()) + self.assertIn(response.status_code, [301, 302, 200]) + + response = self.client.post(reverse('account:login'), { + 'username': 'user1233', + 'password': 'password123' + }) + self.assertIn(response.status_code, [301, 302, 200]) + + response = self.client.get(article.get_admin_url()) + self.assertIn(response.status_code, [301, 302, 200]) + + def test_verify_email_code(self): + to_email = "admin@admin.com" + code = generate_code() + utils.set_code(to_email, code) + utils.send_verify_email(to_email, code) + + err = utils.verify("admin@admin.com", code) + self.assertEqual(err, None) + + err = utils.verify("admin@123.com", code) + self.assertEqual(type(err), str) + + def test_forget_password_email_code_success(self): + resp = self.client.post( + path=reverse("account:forget_password_code"), + data=dict(email="admin@admin.com") + ) + + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.content.decode("utf-8"), "ok") + + def test_forget_password_email_code_fail(self): + resp = self.client.post( + path=reverse("account:forget_password_code"), + data=dict() + ) + self.assertEqual(resp.content.decode("utf-8"), "错误的邮箱") + + resp = self.client.post( + path=reverse("account:forget_password_code"), + data=dict(email="admin@com") + ) + self.assertEqual(resp.content.decode("utf-8"), "错误的邮箱") + + def test_forget_password_email_success(self): + code = generate_code() + utils.set_code(self.blog_user.email, code) + data = dict( + new_password1=self.new_test, + new_password2=self.new_test, + email=self.blog_user.email, + code=code, + ) + resp = self.client.post( + path=reverse("account:forget_password"), + data=data + ) + self.assertEqual(resp.status_code, 302) + + # 验证用户密码是否修改成功 + blog_user = BlogUser.objects.filter( + email=self.blog_user.email, + ).first() # type: BlogUser + self.assertNotEqual(blog_user, None) + self.assertEqual(blog_user.check_password(data["new_password1"]), True) + + def test_forget_password_email_not_user(self): + data = dict( + new_password1=self.new_test, + new_password2=self.new_test, + email="123@123.com", + code="123456", + ) + resp = self.client.post( + path=reverse("account:forget_password"), + data=data + ) + + self.assertEqual(resp.status_code, 200) + + + def test_forget_password_email_code_error(self): + code = generate_code() + utils.set_code(self.blog_user.email, code) + data = dict( + new_password1=self.new_test, + new_password2=self.new_test, + email=self.blog_user.email, + code="111111", + ) + resp = self.client.post( + path=reverse("account:forget_password"), + data=data + ) + + self.assertEqual(resp.status_code, 200) + diff --git a/accounts/urls.py b/accounts/urls.py new file mode 100644 index 0000000..107a801 --- /dev/null +++ b/accounts/urls.py @@ -0,0 +1,28 @@ +from django.urls import path +from django.urls import re_path + +from . import views +from .forms import LoginForm + +app_name = "accounts" + +urlpatterns = [re_path(r'^login/$', + views.LoginView.as_view(success_url='/'), + name='login', + kwargs={'authentication_form': LoginForm}), + re_path(r'^register/$', + views.RegisterView.as_view(success_url="/"), + name='register'), + re_path(r'^logout/$', + views.LogoutView.as_view(), + name='logout'), + path(r'account/result.html', + views.account_result, + name='result'), + re_path(r'^forget_password/$', + views.ForgetPasswordView.as_view(), + name='forget_password'), + re_path(r'^forget_password_code/$', + views.ForgetPasswordEmailCode.as_view(), + name='forget_password_code'), + ] diff --git a/accounts/user_login_backend.py b/accounts/user_login_backend.py new file mode 100644 index 0000000..73cdca1 --- /dev/null +++ b/accounts/user_login_backend.py @@ -0,0 +1,26 @@ +from django.contrib.auth import get_user_model +from django.contrib.auth.backends import ModelBackend + + +class EmailOrUsernameModelBackend(ModelBackend): + """ + 允许使用用户名或邮箱登录 + """ + + def authenticate(self, request, username=None, password=None, **kwargs): + if '@' in username: + kwargs = {'email': username} + else: + kwargs = {'username': username} + try: + user = get_user_model().objects.get(**kwargs) + if user.check_password(password): + return user + except get_user_model().DoesNotExist: + return None + + def get_user(self, username): + try: + return get_user_model().objects.get(pk=username) + except get_user_model().DoesNotExist: + return None diff --git a/accounts/utils.py b/accounts/utils.py new file mode 100644 index 0000000..4b94bdf --- /dev/null +++ b/accounts/utils.py @@ -0,0 +1,49 @@ +import typing +from datetime import timedelta + +from django.core.cache import cache +from django.utils.translation import gettext +from django.utils.translation import gettext_lazy as _ + +from djangoblog.utils import send_email + +_code_ttl = timedelta(minutes=5) + + +def send_verify_email(to_mail: str, code: str, subject: str = _("Verify Email")): + """发送重设密码验证码 + Args: + to_mail: 接受邮箱 + subject: 邮件主题 + code: 验证码 + """ + html_content = _( + "You are resetting the password, the verification code is:%(code)s, valid within 5 minutes, please keep it " + "properly") % {'code': code} + send_email([to_mail], subject, html_content) + + +def verify(email: str, code: str) -> typing.Optional[str]: + """验证code是否有效 + Args: + email: 请求邮箱 + code: 验证码 + Return: + 如果有错误就返回错误str + Node: + 这里的错误处理不太合理,应该采用raise抛出 + 否测调用方也需要对error进行处理 + """ + cache_code = get_code(email) + if cache_code != code: + return gettext("Verification code error") + + +def set_code(email: str, code: str): + """设置code""" + cache.set(email, code, _code_ttl.seconds) + + +def get_code(email: str) -> typing.Optional[str]: + """获取code""" + return cache.get(email) diff --git a/accounts/views.py b/accounts/views.py new file mode 100644 index 0000000..ae67aec --- /dev/null +++ b/accounts/views.py @@ -0,0 +1,204 @@ +import logging +from django.utils.translation import gettext_lazy as _ +from django.conf import settings +from django.contrib import auth +from django.contrib.auth import REDIRECT_FIELD_NAME +from django.contrib.auth import get_user_model +from django.contrib.auth import logout +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.hashers import make_password +from django.http import HttpResponseRedirect, HttpResponseForbidden +from django.http.request import HttpRequest +from django.http.response import HttpResponse +from django.shortcuts import get_object_or_404 +from django.shortcuts import render +from django.urls import reverse +from django.utils.decorators import method_decorator +from django.utils.http import url_has_allowed_host_and_scheme +from django.views import View +from django.views.decorators.cache import never_cache +from django.views.decorators.csrf import csrf_protect +from django.views.decorators.debug import sensitive_post_parameters +from django.views.generic import FormView, RedirectView + +from djangoblog.utils import send_email, get_sha256, get_current_site, generate_code, delete_sidebar_cache +from . import utils +from .forms import RegisterForm, LoginForm, ForgetPasswordForm, ForgetPasswordCodeForm +from .models import BlogUser + +logger = logging.getLogger(__name__) + + +# Create your views here. + +class RegisterView(FormView): + form_class = RegisterForm + template_name = 'account/registration_form.html' + + @method_decorator(csrf_protect) + def dispatch(self, *args, **kwargs): + return super(RegisterView, self).dispatch(*args, **kwargs) + + def form_valid(self, form): + if form.is_valid(): + user = form.save(False) + user.is_active = False + user.source = 'Register' + user.save(True) + site = get_current_site().domain + sign = get_sha256(get_sha256(settings.SECRET_KEY + str(user.id))) + + 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) + + content = """ +

请点击下面链接验证您的邮箱

+ + {url} + + 再次感谢您! +
+ 如果上面链接无法打开,请将此链接复制至浏览器。 + {url} + """.format(url=url) + 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({ + 'form': form + }) + + +class LogoutView(RedirectView): + url = '/login/' + + @method_decorator(never_cache) + def dispatch(self, request, *args, **kwargs): + return super(LogoutView, self).dispatch(request, *args, **kwargs) + + def get(self, request, *args, **kwargs): + logout(request) + delete_sidebar_cache() + return super(LogoutView, self).get(request, *args, **kwargs) + + +class LoginView(FormView): + form_class = LoginForm + template_name = 'account/login.html' + success_url = '/' + redirect_field_name = REDIRECT_FIELD_NAME + login_ttl = 2626560 # 一个月的时间 + + @method_decorator(sensitive_post_parameters('password')) + @method_decorator(csrf_protect) + @method_decorator(never_cache) + def dispatch(self, request, *args, **kwargs): + + return super(LoginView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + redirect_to = self.request.GET.get(self.redirect_field_name) + if redirect_to is None: + redirect_to = '/' + kwargs['redirect_to'] = redirect_to + + return super(LoginView, self).get_context_data(**kwargs) + + def form_valid(self, form): + form = AuthenticationForm(data=self.request.POST, request=self.request) + + if form.is_valid(): + delete_sidebar_cache() + logger.info(self.redirect_field_name) + + auth.login(self.request, form.get_user()) + if self.request.POST.get("remember"): + self.request.session.set_expiry(self.login_ttl) + return super(LoginView, self).form_valid(form) + # return HttpResponseRedirect('/') + else: + return self.render_to_response({ + 'form': form + }) + + def get_success_url(self): + + redirect_to = self.request.POST.get(self.redirect_field_name) + if not url_has_allowed_host_and_scheme( + url=redirect_to, allowed_hosts=[ + self.request.get_host()]): + redirect_to = self.success_url + return redirect_to + + +def account_result(request): + type = request.GET.get('type') + id = request.GET.get('id') + + user = get_object_or_404(get_user_model(), id=id) + logger.info(type) + if user.is_active: + return HttpResponseRedirect('/') + if type and type in ['register', 'validation']: + if type == 'register': + content = ''' + 恭喜您注册成功,一封验证邮件已经发送到您的邮箱,请验证您的邮箱后登录本站。 + ''' + title = '注册成功' + else: + c_sign = get_sha256(get_sha256(settings.SECRET_KEY + str(user.id))) + sign = request.GET.get('sign') + if sign != c_sign: + return HttpResponseForbidden() + user.is_active = True + user.save() + content = ''' + 恭喜您已经成功的完成邮箱验证,您现在可以使用您的账号来登录本站。 + ''' + title = '验证成功' + return render(request, 'account/result.html', { + 'title': title, + 'content': content + }) + else: + return HttpResponseRedirect('/') + + +class ForgetPasswordView(FormView): + form_class = ForgetPasswordForm + template_name = 'account/forget_password.html' + + def form_valid(self, form): + if form.is_valid(): + blog_user = BlogUser.objects.filter(email=form.cleaned_data.get("email")).get() + blog_user.password = make_password(form.cleaned_data["new_password2"]) + blog_user.save() + return HttpResponseRedirect('/login/') + else: + return self.render_to_response({'form': form}) + + +class ForgetPasswordEmailCode(View): + + def post(self, request: HttpRequest): + form = ForgetPasswordCodeForm(request.POST) + if not form.is_valid(): + return HttpResponse("错误的邮箱") + to_email = form.cleaned_data["email"] + + code = generate_code() + utils.send_verify_email(to_email, code) + utils.set_code(to_email, code) + + return HttpResponse("ok") diff --git a/blog/__init__.py b/blog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/admin.py b/blog/admin.py new file mode 100644 index 0000000..46c3420 --- /dev/null +++ b/blog/admin.py @@ -0,0 +1,112 @@ +from django import forms +from django.contrib import admin +from django.contrib.auth import get_user_model +from django.urls import reverse +from django.utils.html import format_html +from django.utils.translation import gettext_lazy as _ + +# Register your models here. +from .models import Article + + +class ArticleForm(forms.ModelForm): + # body = forms.CharField(widget=AdminPagedownWidget()) + + class Meta: + model = Article + fields = '__all__' + + +def makr_article_publish(modeladmin, request, queryset): + queryset.update(status='p') + + +def draft_article(modeladmin, request, queryset): + queryset.update(status='d') + + +def close_article_commentstatus(modeladmin, request, queryset): + queryset.update(comment_status='c') + + +def open_article_commentstatus(modeladmin, request, queryset): + queryset.update(comment_status='o') + + +makr_article_publish.short_description = _('Publish selected articles') +draft_article.short_description = _('Draft selected articles') +close_article_commentstatus.short_description = _('Close article comments') +open_article_commentstatus.short_description = _('Open article comments') + + +class ArticlelAdmin(admin.ModelAdmin): + list_per_page = 20 + search_fields = ('body', 'title') + form = ArticleForm + list_display = ( + 'id', + 'title', + 'author', + 'link_to_category', + 'creation_time', + 'views', + 'status', + 'type', + 'article_order') + list_display_links = ('id', 'title') + list_filter = ('status', 'type', 'category') + filter_horizontal = ('tags',) + exclude = ('creation_time', 'last_modify_time') + view_on_site = True + 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) + link = reverse('admin:%s_%s_change' % info, args=(obj.category.id,)) + return format_html(u'%s' % (link, obj.category.name)) + + link_to_category.short_description = _('category') + + 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) + return form + + def save_model(self, request, obj, form, change): + super(ArticlelAdmin, self).save_model(request, obj, form, change) + + def get_view_on_site_url(self, obj=None): + if obj: + url = obj.get_full_url() + return url + else: + from djangoblog.utils import get_current_site + site = get_current_site().domain + return site + + +class TagAdmin(admin.ModelAdmin): + exclude = ('slug', 'last_mod_time', 'creation_time') + + +class CategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'parent_category', 'index') + exclude = ('slug', 'last_mod_time', 'creation_time') + + +class LinksAdmin(admin.ModelAdmin): + exclude = ('last_mod_time', 'creation_time') + + +class SideBarAdmin(admin.ModelAdmin): + list_display = ('name', 'content', 'is_enable', 'sequence') + exclude = ('last_mod_time', 'creation_time') + + +class BlogSettingsAdmin(admin.ModelAdmin): + pass diff --git a/blog/apps.py b/blog/apps.py new file mode 100644 index 0000000..7930587 --- /dev/null +++ b/blog/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BlogConfig(AppConfig): + name = 'blog' diff --git a/blog/context_processors.py b/blog/context_processors.py new file mode 100644 index 0000000..73e3088 --- /dev/null +++ b/blog/context_processors.py @@ -0,0 +1,43 @@ +import logging + +from django.utils import timezone + +from djangoblog.utils import cache, get_blog_setting +from .models import Category, Article + +logger = logging.getLogger(__name__) + + +def seo_processor(requests): + key = 'seo_processor' + value = cache.get(key) + if value: + return value + else: + logger.info('set processor cache.') + setting = get_blog_setting() + value = { + 'SITE_NAME': setting.site_name, + 'SHOW_GOOGLE_ADSENSE': setting.show_google_adsense, + 'GOOGLE_ADSENSE_CODES': setting.google_adsense_codes, + 'SITE_SEO_DESCRIPTION': setting.site_seo_description, + 'SITE_DESCRIPTION': setting.site_description, + 'SITE_KEYWORDS': setting.site_keywords, + 'SITE_BASE_URL': requests.scheme + '://' + requests.get_host() + '/', + 'ARTICLE_SUB_LENGTH': setting.article_sub_length, + 'nav_category_list': Category.objects.all(), + 'nav_pages': Article.objects.filter( + type='p', + status='p'), + 'OPEN_SITE_COMMENT': setting.open_site_comment, + 'BEIAN_CODE': setting.beian_code, + 'ANALYTICS_CODE': setting.analytics_code, + "BEIAN_CODE_GONGAN": setting.gongan_beiancode, + "SHOW_GONGAN_CODE": setting.show_gongan_code, + "CURRENT_YEAR": timezone.now().year, + "GLOBAL_HEADER": setting.global_header, + "GLOBAL_FOOTER": setting.global_footer, + "COMMENT_NEED_REVIEW": setting.comment_need_review, + } + cache.set(key, value, 60 * 60 * 10) + return value diff --git a/blog/documents.py b/blog/documents.py new file mode 100644 index 0000000..0f1db7b --- /dev/null +++ b/blog/documents.py @@ -0,0 +1,213 @@ +import time + +import elasticsearch.client +from django.conf import settings +from elasticsearch_dsl import Document, InnerDoc, Date, Integer, Long, Text, Object, GeoPoint, Keyword, Boolean +from elasticsearch_dsl.connections import connections + +from blog.models import Article + +ELASTICSEARCH_ENABLED = hasattr(settings, 'ELASTICSEARCH_DSL') + +if ELASTICSEARCH_ENABLED: + connections.create_connection( + hosts=[settings.ELASTICSEARCH_DSL['default']['hosts']]) + from elasticsearch import Elasticsearch + + es = Elasticsearch(settings.ELASTICSEARCH_DSL['default']['hosts']) + from elasticsearch.client import IngestClient + + c = IngestClient(es) + try: + c.get_pipeline('geoip') + except elasticsearch.exceptions.NotFoundError: + c.put_pipeline('geoip', body='''{ + "description" : "Add geoip info", + "processors" : [ + { + "geoip" : { + "field" : "ip" + } + } + ] + }''') + + +class GeoIp(InnerDoc): + continent_name = Keyword() + country_iso_code = Keyword() + country_name = Keyword() + location = GeoPoint() + + +class UserAgentBrowser(InnerDoc): + Family = Keyword() + Version = Keyword() + + +class UserAgentOS(UserAgentBrowser): + pass + + +class UserAgentDevice(InnerDoc): + Family = Keyword() + Brand = Keyword() + Model = Keyword() + + +class UserAgent(InnerDoc): + browser = Object(UserAgentBrowser, required=False) + os = Object(UserAgentOS, required=False) + device = Object(UserAgentDevice, required=False) + string = Text() + is_bot = Boolean() + + +class ElapsedTimeDocument(Document): + url = Keyword() + time_taken = Long() + log_datetime = Date() + ip = Keyword() + geoip = Object(GeoIp, required=False) + useragent = Object(UserAgent, required=False) + + class Index: + name = 'performance' + settings = { + "number_of_shards": 1, + "number_of_replicas": 0 + } + + class Meta: + doc_type = 'ElapsedTime' + + +class ElaspedTimeDocumentManager: + @staticmethod + def build_index(): + from elasticsearch import Elasticsearch + client = Elasticsearch(settings.ELASTICSEARCH_DSL['default']['hosts']) + res = client.indices.exists(index="performance") + if not res: + ElapsedTimeDocument.init() + + @staticmethod + def delete_index(): + from elasticsearch import Elasticsearch + es = Elasticsearch(settings.ELASTICSEARCH_DSL['default']['hosts']) + es.indices.delete(index='performance', ignore=[400, 404]) + + @staticmethod + def create(url, time_taken, log_datetime, useragent, ip): + ElaspedTimeDocumentManager.build_index() + ua = UserAgent() + ua.browser = UserAgentBrowser() + ua.browser.Family = useragent.browser.family + ua.browser.Version = useragent.browser.version_string + + ua.os = UserAgentOS() + ua.os.Family = useragent.os.family + ua.os.Version = useragent.os.version_string + + ua.device = UserAgentDevice() + ua.device.Family = useragent.device.family + ua.device.Brand = useragent.device.brand + ua.device.Model = useragent.device.model + ua.string = useragent.ua_string + ua.is_bot = useragent.is_bot + + doc = ElapsedTimeDocument( + meta={ + 'id': int( + round( + time.time() * + 1000)) + }, + url=url, + time_taken=time_taken, + log_datetime=log_datetime, + useragent=ua, ip=ip) + doc.save(pipeline="geoip") + + +class ArticleDocument(Document): + body = Text(analyzer='ik_max_word', search_analyzer='ik_smart') + title = Text(analyzer='ik_max_word', search_analyzer='ik_smart') + author = Object(properties={ + 'nickname': Text(analyzer='ik_max_word', search_analyzer='ik_smart'), + 'id': Integer() + }) + category = Object(properties={ + 'name': Text(analyzer='ik_max_word', search_analyzer='ik_smart'), + 'id': Integer() + }) + tags = Object(properties={ + 'name': Text(analyzer='ik_max_word', search_analyzer='ik_smart'), + 'id': Integer() + }) + + pub_time = Date() + status = Text() + comment_status = Text() + type = Text() + views = Integer() + article_order = Integer() + + class Index: + name = 'blog' + settings = { + "number_of_shards": 1, + "number_of_replicas": 0 + } + + class Meta: + doc_type = 'Article' + + +class ArticleDocumentManager(): + + def __init__(self): + self.create_index() + + def create_index(self): + ArticleDocument.init() + + def delete_index(self): + from elasticsearch import Elasticsearch + es = Elasticsearch(settings.ELASTICSEARCH_DSL['default']['hosts']) + 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={ + 'nickname': 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() + articles = articles if articles else Article.objects.all() + docs = self.convert_to_doc(articles) + for doc in docs: + doc.save() + + def update_docs(self, docs): + for doc in docs: + doc.save() diff --git a/blog/forms.py b/blog/forms.py new file mode 100644 index 0000000..715be76 --- /dev/null +++ b/blog/forms.py @@ -0,0 +1,19 @@ +import logging + +from django import forms +from haystack.forms import SearchForm + +logger = logging.getLogger(__name__) + + +class BlogSearchForm(SearchForm): + querydata = forms.CharField(required=True) + + def search(self): + datas = super(BlogSearchForm, self).search() + if not self.is_valid(): + return self.no_query_found() + + if self.cleaned_data['querydata']: + logger.info(self.cleaned_data['querydata']) + return datas diff --git a/blog/management/__init__.py b/blog/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/management/commands/__init__.py b/blog/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/management/commands/build_index.py b/blog/management/commands/build_index.py new file mode 100644 index 0000000..3c4acd7 --- /dev/null +++ b/blog/management/commands/build_index.py @@ -0,0 +1,18 @@ +from django.core.management.base import BaseCommand + +from blog.documents import ElapsedTimeDocument, ArticleDocumentManager, ElaspedTimeDocumentManager, \ + ELASTICSEARCH_ENABLED + + +# TODO 参数化 +class Command(BaseCommand): + help = 'build search index' + + def handle(self, *args, **options): + if ELASTICSEARCH_ENABLED: + ElaspedTimeDocumentManager.build_index() + manager = ElapsedTimeDocument() + manager.init() + manager = ArticleDocumentManager() + manager.delete_index() + manager.rebuild() diff --git a/blog/management/commands/build_search_words.py b/blog/management/commands/build_search_words.py new file mode 100644 index 0000000..cfe7e0d --- /dev/null +++ b/blog/management/commands/build_search_words.py @@ -0,0 +1,13 @@ +from django.core.management.base import BaseCommand + +from blog.models import Tag, Category + + +# TODO 参数化 +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()]) + print('\n'.join(datas)) diff --git a/blog/management/commands/clear_cache.py b/blog/management/commands/clear_cache.py new file mode 100644 index 0000000..0d66172 --- /dev/null +++ b/blog/management/commands/clear_cache.py @@ -0,0 +1,11 @@ +from django.core.management.base import BaseCommand + +from djangoblog.utils import cache + + +class Command(BaseCommand): + help = 'clear the whole cache' + + def handle(self, *args, **options): + cache.clear() + self.stdout.write(self.style.SUCCESS('Cleared cache\n')) diff --git a/blog/management/commands/create_testdata.py b/blog/management/commands/create_testdata.py new file mode 100644 index 0000000..675d2ba --- /dev/null +++ b/blog/management/commands/create_testdata.py @@ -0,0 +1,40 @@ +from django.contrib.auth import get_user_model +from django.contrib.auth.hashers import make_password +from django.core.management.base import BaseCommand + +from blog.models import Article, Tag, Category + + +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=make_password('test!q@w#eTYU'))[0] + + pcategory = Category.objects.get_or_create( + name='我是父类目', parent_category=None)[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] + tag = Tag() + tag.name = "标签" + str(i) + tag.save() + article.tags.add(tag) + article.tags.add(basetag) + article.save() + + from djangoblog.utils import cache + cache.clear() + self.stdout.write(self.style.SUCCESS('created test datas \n')) diff --git a/blog/management/commands/ping_baidu.py b/blog/management/commands/ping_baidu.py new file mode 100644 index 0000000..2c7fbdd --- /dev/null +++ b/blog/management/commands/ping_baidu.py @@ -0,0 +1,50 @@ +from django.core.management.base import BaseCommand + +from djangoblog.spider_notify import SpiderNotify +from djangoblog.utils import get_current_site +from blog.models import Article, Tag, Category + +site = get_current_site().domain + + +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') + + def get_full_url(self, path): + url = "https://{site}{path}".format(site=site, path=path) + return url + + def handle(self, *args, **options): + type = options['data_type'] + self.stdout.write('start get %s' % type) + + urls = [] + if type == 'article' or type == 'all': + for article in Article.objects.filter(status='p'): + urls.append(article.get_full_url()) + if type == 'tag' or type == 'all': + for tag in Tag.objects.all(): + url = tag.get_absolute_url() + urls.append(self.get_full_url(url)) + if type == 'category' or type == 'all': + for category in Category.objects.all(): + url = category.get_absolute_url() + urls.append(self.get_full_url(url)) + + 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 new file mode 100644 index 0000000..d0f4612 --- /dev/null +++ b/blog/management/commands/sync_user_avatar.py @@ -0,0 +1,47 @@ +import requests +from django.core.management.base import BaseCommand +from django.templatetags.static import static + +from djangoblog.utils import save_user_avatar +from oauth.models import OAuthUser +from oauth.oauthmanager import get_manager_by_type + + +class Command(BaseCommand): + help = 'sync user avatar' + + def test_picture(self, url): + try: + if requests.get(url, timeout=2).status_code == 200: + return True + except: + pass + + def handle(self, *args, **options): + static_url = static("../") + users = OAuthUser.objects.all() + self.stdout.write(f'开始同步{len(users)}个用户头像') + for u in users: + self.stdout.write(f'开始同步:{u.nickname}') + url = u.picture + if url: + if url.startswith(static_url): + if self.test_picture(url): + continue + else: + if u.metadata: + manage = get_manager_by_type(u.type) + url = manage.get_picture(u.metadata) + url = save_user_avatar(url) + else: + url = static('blog/img/avatar.png') + else: + url = save_user_avatar(url) + else: + url = static('blog/img/avatar.png') + if url: + self.stdout.write( + f'结束同步:{u.nickname}.url:{url}') + u.picture = url + u.save() + self.stdout.write('结束同步') diff --git a/blog/middleware.py b/blog/middleware.py new file mode 100644 index 0000000..94dd70c --- /dev/null +++ b/blog/middleware.py @@ -0,0 +1,42 @@ +import logging +import time + +from ipware import get_client_ip +from user_agents import parse + +from blog.documents import ELASTICSEARCH_ENABLED, ElaspedTimeDocumentManager + +logger = logging.getLogger(__name__) + + +class OnlineMiddleware(object): + def __init__(self, get_response=None): + self.get_response = get_response + super().__init__() + + def __call__(self, request): + ''' page render time ''' + start_time = time.time() + response = self.get_response(request) + http_user_agent = request.META.get('HTTP_USER_AGENT', '') + ip, _ = get_client_ip(request) + user_agent = parse(http_user_agent) + if not response.streaming: + try: + cast_time = time.time() - start_time + if ELASTICSEARCH_ENABLED: + time_taken = round((cast_time) * 1000, 2) + url = request.path + from django.utils import timezone + ElaspedTimeDocumentManager.create( + url=url, + time_taken=time_taken, + log_datetime=timezone.now(), + useragent=user_agent, + ip=ip) + 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/migrations/0001_initial.py b/blog/migrations/0001_initial.py new file mode 100644 index 0000000..3d391b6 --- /dev/null +++ b/blog/migrations/0001_initial.py @@ -0,0 +1,137 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import mdeditor.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='BlogSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sitename', models.CharField(default='', max_length=200, verbose_name='网站名称')), + ('site_description', models.TextField(default='', max_length=1000, verbose_name='网站描述')), + ('site_seo_description', models.TextField(default='', max_length=1000, verbose_name='网站SEO描述')), + ('site_keywords', models.TextField(default='', max_length=1000, verbose_name='网站关键字')), + ('article_sub_length', models.IntegerField(default=300, verbose_name='文章摘要长度')), + ('sidebar_article_count', models.IntegerField(default=10, verbose_name='侧边栏文章数目')), + ('sidebar_comment_count', models.IntegerField(default=5, verbose_name='侧边栏评论数目')), + ('article_comment_count', models.IntegerField(default=5, verbose_name='文章页面默认显示评论数目')), + ('show_google_adsense', models.BooleanField(default=False, verbose_name='是否显示谷歌广告')), + ('google_adsense_codes', models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='广告内容')), + ('open_site_comment', models.BooleanField(default=True, verbose_name='是否打开网站评论功能')), + ('beiancode', models.CharField(blank=True, default='', max_length=2000, null=True, verbose_name='备案号')), + ('analyticscode', models.TextField(default='', max_length=1000, verbose_name='网站统计代码')), + ('show_gongan_code', models.BooleanField(default=False, verbose_name='是否显示公安备案号')), + ('gongan_beiancode', models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='公安备案号')), + ], + options={ + 'verbose_name': '网站配置', + 'verbose_name_plural': '网站配置', + }, + ), + migrations.CreateModel( + name='Links', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='链接名称')), + ('link', models.URLField(verbose_name='链接地址')), + ('sequence', models.IntegerField(unique=True, verbose_name='排序')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('show_type', models.CharField(choices=[('i', '首页'), ('l', '列表页'), ('p', '文章页面'), ('a', '全站'), ('s', '友情链接页面')], default='i', max_length=1, verbose_name='显示类型')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '友情链接', + 'verbose_name_plural': '友情链接', + 'ordering': ['sequence'], + }, + ), + migrations.CreateModel( + name='SideBar', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='标题')), + ('content', models.TextField(verbose_name='内容')), + ('sequence', models.IntegerField(unique=True, verbose_name='排序')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否启用')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '侧边栏', + 'verbose_name_plural': '侧边栏', + 'ordering': ['sequence'], + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='标签名')), + ('slug', models.SlugField(blank=True, default='no-slug', max_length=60)), + ], + options={ + 'verbose_name': '标签', + 'verbose_name_plural': '标签', + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='分类名')), + ('slug', models.SlugField(blank=True, default='no-slug', max_length=60)), + ('index', models.IntegerField(default=0, verbose_name='权重排序-越大越靠前')), + ('parent_category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='父级分类')), + ], + options={ + 'verbose_name': '分类', + 'verbose_name_plural': '分类', + 'ordering': ['-index'], + }, + ), + migrations.CreateModel( + name='Article', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('title', models.CharField(max_length=200, unique=True, verbose_name='标题')), + ('body', mdeditor.fields.MDTextField(verbose_name='正文')), + ('pub_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='发布时间')), + ('status', models.CharField(choices=[('d', '草稿'), ('p', '发表')], default='p', max_length=1, verbose_name='文章状态')), + ('comment_status', models.CharField(choices=[('o', '打开'), ('c', '关闭')], default='o', max_length=1, verbose_name='评论状态')), + ('type', models.CharField(choices=[('a', '文章'), ('p', '页面')], default='a', max_length=1, verbose_name='类型')), + ('views', models.PositiveIntegerField(default=0, verbose_name='浏览量')), + ('article_order', models.IntegerField(default=0, verbose_name='排序,数字越大越靠前')), + ('show_toc', models.BooleanField(default=False, verbose_name='是否显示toc目录')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='分类')), + ('tags', models.ManyToManyField(blank=True, to='blog.tag', verbose_name='标签集合')), + ], + options={ + 'verbose_name': '文章', + 'verbose_name_plural': '文章', + 'ordering': ['-article_order', '-pub_time'], + 'get_latest_by': 'id', + }, + ), + ] diff --git a/blog/migrations/0002_blogsettings_global_footer_and_more.py b/blog/migrations/0002_blogsettings_global_footer_and_more.py new file mode 100644 index 0000000..adbaa36 --- /dev/null +++ b/blog/migrations/0002_blogsettings_global_footer_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.7 on 2023-03-29 06:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='blogsettings', + name='global_footer', + field=models.TextField(blank=True, default='', null=True, verbose_name='公共尾部'), + ), + migrations.AddField( + model_name='blogsettings', + name='global_header', + field=models.TextField(blank=True, default='', null=True, verbose_name='公共头部'), + ), + ] diff --git a/blog/migrations/0003_blogsettings_comment_need_review.py b/blog/migrations/0003_blogsettings_comment_need_review.py new file mode 100644 index 0000000..e9f5502 --- /dev/null +++ b/blog/migrations/0003_blogsettings_comment_need_review.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.1 on 2023-05-09 07:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('blog', '0002_blogsettings_global_footer_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='blogsettings', + name='comment_need_review', + field=models.BooleanField(default=False, verbose_name='评论是否需要审核'), + ), + ] diff --git a/blog/migrations/0004_rename_analyticscode_blogsettings_analytics_code_and_more.py b/blog/migrations/0004_rename_analyticscode_blogsettings_analytics_code_and_more.py new file mode 100644 index 0000000..ceb1398 --- /dev/null +++ b/blog/migrations/0004_rename_analyticscode_blogsettings_analytics_code_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.1 on 2023-05-09 07:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('blog', '0003_blogsettings_comment_need_review'), + ] + + operations = [ + migrations.RenameField( + model_name='blogsettings', + old_name='analyticscode', + new_name='analytics_code', + ), + migrations.RenameField( + model_name='blogsettings', + old_name='beiancode', + new_name='beian_code', + ), + migrations.RenameField( + model_name='blogsettings', + old_name='sitename', + new_name='site_name', + ), + ] diff --git a/blog/migrations/0005_alter_article_options_alter_category_options_and_more.py b/blog/migrations/0005_alter_article_options_alter_category_options_and_more.py new file mode 100644 index 0000000..d08e853 --- /dev/null +++ b/blog/migrations/0005_alter_article_options_alter_category_options_and_more.py @@ -0,0 +1,300 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:13 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import mdeditor.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('blog', '0004_rename_analyticscode_blogsettings_analytics_code_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='article', + options={'get_latest_by': 'id', 'ordering': ['-article_order', '-pub_time'], 'verbose_name': 'article', 'verbose_name_plural': 'article'}, + ), + migrations.AlterModelOptions( + name='category', + options={'ordering': ['-index'], 'verbose_name': 'category', 'verbose_name_plural': 'category'}, + ), + migrations.AlterModelOptions( + name='links', + options={'ordering': ['sequence'], 'verbose_name': 'link', 'verbose_name_plural': 'link'}, + ), + migrations.AlterModelOptions( + name='sidebar', + options={'ordering': ['sequence'], 'verbose_name': 'sidebar', 'verbose_name_plural': 'sidebar'}, + ), + migrations.AlterModelOptions( + name='tag', + options={'ordering': ['name'], 'verbose_name': 'tag', 'verbose_name_plural': 'tag'}, + ), + migrations.RemoveField( + model_name='article', + name='created_time', + ), + migrations.RemoveField( + model_name='article', + name='last_mod_time', + ), + migrations.RemoveField( + model_name='category', + name='created_time', + ), + migrations.RemoveField( + model_name='category', + name='last_mod_time', + ), + migrations.RemoveField( + model_name='links', + name='created_time', + ), + migrations.RemoveField( + model_name='sidebar', + name='created_time', + ), + migrations.RemoveField( + model_name='tag', + name='created_time', + ), + migrations.RemoveField( + model_name='tag', + name='last_mod_time', + ), + migrations.AddField( + model_name='article', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='article', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'), + ), + migrations.AddField( + model_name='category', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='category', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'), + ), + migrations.AddField( + model_name='links', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='sidebar', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='tag', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='tag', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'), + ), + migrations.AlterField( + model_name='article', + name='article_order', + field=models.IntegerField(default=0, verbose_name='order'), + ), + migrations.AlterField( + model_name='article', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'), + ), + migrations.AlterField( + model_name='article', + name='body', + field=mdeditor.fields.MDTextField(verbose_name='body'), + ), + migrations.AlterField( + model_name='article', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='category'), + ), + migrations.AlterField( + model_name='article', + name='comment_status', + field=models.CharField(choices=[('o', 'Open'), ('c', 'Close')], default='o', max_length=1, verbose_name='comment status'), + ), + migrations.AlterField( + model_name='article', + name='pub_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='publish time'), + ), + migrations.AlterField( + model_name='article', + name='show_toc', + field=models.BooleanField(default=False, verbose_name='show toc'), + ), + migrations.AlterField( + model_name='article', + name='status', + field=models.CharField(choices=[('d', 'Draft'), ('p', 'Published')], default='p', max_length=1, verbose_name='status'), + ), + migrations.AlterField( + model_name='article', + name='tags', + field=models.ManyToManyField(blank=True, to='blog.tag', verbose_name='tag'), + ), + migrations.AlterField( + model_name='article', + name='title', + field=models.CharField(max_length=200, unique=True, verbose_name='title'), + ), + migrations.AlterField( + model_name='article', + name='type', + field=models.CharField(choices=[('a', 'Article'), ('p', 'Page')], default='a', max_length=1, verbose_name='type'), + ), + migrations.AlterField( + model_name='article', + name='views', + field=models.PositiveIntegerField(default=0, verbose_name='views'), + ), + migrations.AlterField( + model_name='blogsettings', + name='article_comment_count', + field=models.IntegerField(default=5, verbose_name='article comment count'), + ), + migrations.AlterField( + model_name='blogsettings', + name='article_sub_length', + field=models.IntegerField(default=300, verbose_name='article sub length'), + ), + migrations.AlterField( + model_name='blogsettings', + name='google_adsense_codes', + field=models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='adsense code'), + ), + migrations.AlterField( + model_name='blogsettings', + name='open_site_comment', + field=models.BooleanField(default=True, verbose_name='open site comment'), + ), + migrations.AlterField( + model_name='blogsettings', + name='show_google_adsense', + field=models.BooleanField(default=False, verbose_name='show adsense'), + ), + migrations.AlterField( + model_name='blogsettings', + name='sidebar_article_count', + field=models.IntegerField(default=10, verbose_name='sidebar article count'), + ), + migrations.AlterField( + model_name='blogsettings', + name='sidebar_comment_count', + field=models.IntegerField(default=5, verbose_name='sidebar comment count'), + ), + migrations.AlterField( + model_name='blogsettings', + name='site_description', + field=models.TextField(default='', max_length=1000, verbose_name='site description'), + ), + migrations.AlterField( + model_name='blogsettings', + name='site_keywords', + field=models.TextField(default='', max_length=1000, verbose_name='site keywords'), + ), + migrations.AlterField( + model_name='blogsettings', + name='site_name', + field=models.CharField(default='', max_length=200, verbose_name='site name'), + ), + migrations.AlterField( + model_name='blogsettings', + name='site_seo_description', + field=models.TextField(default='', max_length=1000, verbose_name='site seo description'), + ), + migrations.AlterField( + model_name='category', + name='index', + field=models.IntegerField(default=0, verbose_name='index'), + ), + migrations.AlterField( + model_name='category', + name='name', + field=models.CharField(max_length=30, unique=True, verbose_name='category name'), + ), + migrations.AlterField( + model_name='category', + name='parent_category', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='parent category'), + ), + migrations.AlterField( + model_name='links', + name='is_enable', + field=models.BooleanField(default=True, verbose_name='is show'), + ), + migrations.AlterField( + model_name='links', + name='last_mod_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'), + ), + migrations.AlterField( + model_name='links', + name='link', + field=models.URLField(verbose_name='link'), + ), + migrations.AlterField( + model_name='links', + name='name', + field=models.CharField(max_length=30, unique=True, verbose_name='link name'), + ), + migrations.AlterField( + model_name='links', + name='sequence', + field=models.IntegerField(unique=True, verbose_name='order'), + ), + migrations.AlterField( + model_name='links', + name='show_type', + field=models.CharField(choices=[('i', 'index'), ('l', 'list'), ('p', 'post'), ('a', 'all'), ('s', 'slide')], default='i', max_length=1, verbose_name='show type'), + ), + migrations.AlterField( + model_name='sidebar', + name='content', + field=models.TextField(verbose_name='content'), + ), + migrations.AlterField( + model_name='sidebar', + name='is_enable', + field=models.BooleanField(default=True, verbose_name='is enable'), + ), + migrations.AlterField( + model_name='sidebar', + name='last_mod_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'), + ), + migrations.AlterField( + model_name='sidebar', + name='name', + field=models.CharField(max_length=100, verbose_name='title'), + ), + migrations.AlterField( + model_name='sidebar', + name='sequence', + field=models.IntegerField(unique=True, verbose_name='order'), + ), + migrations.AlterField( + model_name='tag', + name='name', + field=models.CharField(max_length=30, unique=True, verbose_name='tag name'), + ), + ] diff --git a/blog/migrations/0006_alter_blogsettings_options.py b/blog/migrations/0006_alter_blogsettings_options.py new file mode 100644 index 0000000..e36feb4 --- /dev/null +++ b/blog/migrations/0006_alter_blogsettings_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.7 on 2024-01-26 02:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0005_alter_article_options_alter_category_options_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='blogsettings', + options={'verbose_name': 'Website configuration', 'verbose_name_plural': 'Website configuration'}, + ), + ] diff --git a/blog/migrations/__init__.py b/blog/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/models.py b/blog/models.py new file mode 100644 index 0000000..083788b --- /dev/null +++ b/blog/models.py @@ -0,0 +1,376 @@ +import logging +import re +from abc import abstractmethod + +from django.conf import settings +from django.core.exceptions import ValidationError +from django.db import models +from django.urls import reverse +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ +from mdeditor.fields import MDTextField +from uuslug import slugify + +from djangoblog.utils import cache_decorator, cache +from djangoblog.utils import get_current_site + +logger = logging.getLogger(__name__) + + +class LinkShowType(models.TextChoices): + I = ('i', _('index')) + L = ('l', _('list')) + P = ('p', _('post')) + A = ('a', _('all')) + S = ('s', _('slide')) + + +class BaseModel(models.Model): + id = models.AutoField(primary_key=True) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_modify_time = models.DateTimeField(_('modify time'), default=now) + + def save(self, *args, **kwargs): + 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') + 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()) + return url + + class Meta: + abstract = True + + @abstractmethod + def get_absolute_url(self): + pass + + +class Article(BaseModel): + """文章""" + STATUS_CHOICES = ( + ('d', _('Draft')), + ('p', _('Published')), + ) + COMMENT_STATUS = ( + ('o', _('Open')), + ('c', _('Close')), + ) + TYPE = ( + ('a', _('Article')), + ('p', _('Page')), + ) + title = models.CharField(_('title'), max_length=200, unique=True) + body = MDTextField(_('body')) + pub_time = models.DateTimeField( + _('publish time'), blank=False, null=False, default=now) + status = models.CharField( + _('status'), + max_length=1, + choices=STATUS_CHOICES, + default='p') + comment_status = models.CharField( + _('comment status'), + max_length=1, + choices=COMMENT_STATUS, + default='o') + type = models.CharField(_('type'), max_length=1, choices=TYPE, default='a') + views = models.PositiveIntegerField(_('views'), default=0) + author = models.ForeignKey( + settings.AUTH_USER_MODEL, + verbose_name=_('author'), + blank=False, + null=False, + on_delete=models.CASCADE) + article_order = models.IntegerField( + _('order'), blank=False, null=False, default=0) + show_toc = models.BooleanField(_('show toc'), blank=False, null=False, default=False) + category = models.ForeignKey( + 'Category', + verbose_name=_('category'), + on_delete=models.CASCADE, + blank=False, + null=False) + tags = models.ManyToManyField('Tag', verbose_name=_('tag'), blank=True) + + def body_to_string(self): + return self.body + + def __str__(self): + return self.title + + class Meta: + ordering = ['-article_order', '-pub_time'] + verbose_name = _('article') + verbose_name_plural = verbose_name + get_latest_by = 'id' + + def get_absolute_url(self): + return reverse('blog:detailbyid', kwargs={ + 'article_id': self.id, + 'year': self.creation_time.year, + 'month': self.creation_time.month, + 'day': self.creation_time.day + }) + + @cache_decorator(60 * 60 * 10) + def get_category_tree(self): + tree = self.category.get_category_tree() + names = list(map(lambda c: (c.name, c.get_absolute_url()), tree)) + + return names + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + + def viewed(self): + self.views += 1 + self.save(update_fields=['views']) + + def comment_list(self): + cache_key = 'article_comments_{id}'.format(id=self.id) + value = cache.get(cache_key) + if value: + logger.info('get article comments:{id}'.format(id=self.id)) + return value + else: + comments = self.comment_set.filter(is_enable=True).order_by('-id') + cache.set(cache_key, comments, 60 * 100) + logger.info('set article comments:{id}'.format(id=self.id)) + return comments + + def get_admin_url(self): + info = (self._meta.app_label, self._meta.model_name) + return reverse('admin:%s_%s_change' % info, args=(self.pk,)) + + @cache_decorator(expiration=60 * 100) + def next_article(self): + # 下一篇 + return Article.objects.filter( + id__gt=self.id, status='p').order_by('id').first() + + @cache_decorator(expiration=60 * 100) + def prev_article(self): + # 前一篇 + return Article.objects.filter(id__lt=self.id, status='p').first() + + def get_first_image_url(self): + """ + Get the first image url from article.body. + :return: + """ + match = re.search(r'!\[.*?\]\((.+?)\)', self.body) + if match: + return match.group(1) + return "" + + +class Category(BaseModel): + """文章分类""" + name = models.CharField(_('category name'), max_length=30, unique=True) + parent_category = models.ForeignKey( + 'self', + verbose_name=_('parent category'), + blank=True, + null=True, + on_delete=models.CASCADE) + slug = models.SlugField(default='no-slug', max_length=60, blank=True) + index = models.IntegerField(default=0, verbose_name=_('index')) + + class Meta: + ordering = ['-index'] + verbose_name = _('category') + verbose_name_plural = verbose_name + + def get_absolute_url(self): + return reverse( + 'blog:category_detail', kwargs={ + 'category_name': self.slug}) + + def __str__(self): + return self.name + + @cache_decorator(60 * 60 * 10) + def get_category_tree(self): + """ + 递归获得分类目录的父级 + :return: + """ + categorys = [] + + def parse(category): + categorys.append(category) + if category.parent_category: + parse(category.parent_category) + + parse(self) + return categorys + + @cache_decorator(60 * 60 * 10) + def get_sub_categorys(self): + """ + 获得当前分类目录所有子集 + :return: + """ + categorys = [] + all_categorys = Category.objects.all() + + def parse(category): + if category not in categorys: + categorys.append(category) + childs = all_categorys.filter(parent_category=category) + for child in childs: + if category not in categorys: + categorys.append(child) + parse(child) + + parse(self) + return categorys + + +class Tag(BaseModel): + """文章标签""" + name = models.CharField(_('tag name'), max_length=30, unique=True) + slug = models.SlugField(default='no-slug', max_length=60, blank=True) + + def __str__(self): + return self.name + + def get_absolute_url(self): + return reverse('blog:tag_detail', kwargs={'tag_name': self.slug}) + + @cache_decorator(60 * 60 * 10) + def get_article_count(self): + return Article.objects.filter(tags__name=self.name).distinct().count() + + class Meta: + ordering = ['name'] + verbose_name = _('tag') + verbose_name_plural = verbose_name + + +class Links(models.Model): + """友情链接""" + + name = models.CharField(_('link name'), max_length=30, unique=True) + link = models.URLField(_('link')) + sequence = models.IntegerField(_('order'), unique=True) + is_enable = models.BooleanField( + _('is show'), default=True, blank=False, null=False) + show_type = models.CharField( + _('show type'), + max_length=1, + choices=LinkShowType.choices, + default=LinkShowType.I) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_mod_time = models.DateTimeField(_('modify time'), default=now) + + class Meta: + ordering = ['sequence'] + verbose_name = _('link') + verbose_name_plural = verbose_name + + def __str__(self): + return self.name + + +class SideBar(models.Model): + """侧边栏,可以展示一些html内容""" + name = models.CharField(_('title'), max_length=100) + content = models.TextField(_('content')) + sequence = models.IntegerField(_('order'), unique=True) + is_enable = models.BooleanField(_('is enable'), default=True) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_mod_time = models.DateTimeField(_('modify time'), default=now) + + class Meta: + ordering = ['sequence'] + verbose_name = _('sidebar') + verbose_name_plural = verbose_name + + def __str__(self): + return self.name + + +class BlogSettings(models.Model): + """blog的配置""" + site_name = models.CharField( + _('site name'), + max_length=200, + null=False, + blank=False, + default='') + site_description = models.TextField( + _('site description'), + max_length=1000, + null=False, + blank=False, + default='') + site_seo_description = models.TextField( + _('site seo description'), max_length=1000, null=False, blank=False, default='') + site_keywords = models.TextField( + _('site keywords'), + max_length=1000, + null=False, + blank=False, + default='') + article_sub_length = models.IntegerField(_('article sub length'), default=300) + sidebar_article_count = models.IntegerField(_('sidebar article count'), default=10) + sidebar_comment_count = models.IntegerField(_('sidebar comment count'), default=5) + article_comment_count = models.IntegerField(_('article comment count'), default=5) + show_google_adsense = models.BooleanField(_('show adsense'), default=False) + google_adsense_codes = models.TextField( + _('adsense code'), max_length=2000, null=True, blank=True, default='') + open_site_comment = models.BooleanField(_('open site comment'), default=True) + global_header = models.TextField("公共头部", null=True, blank=True, default='') + global_footer = models.TextField("公共尾部", null=True, blank=True, default='') + beian_code = models.CharField( + '备案号', + max_length=2000, + null=True, + blank=True, + default='') + analytics_code = 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='') + comment_need_review = models.BooleanField( + '评论是否需要审核', default=False, null=False) + + class Meta: + verbose_name = _('Website configuration') + verbose_name_plural = verbose_name + + def __str__(self): + return self.site_name + + def clean(self): + if BlogSettings.objects.exclude(id=self.id).count(): + raise ValidationError(_('There can only be one configuration')) + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + from djangoblog.utils import cache + cache.clear() diff --git a/blog/search_indexes.py b/blog/search_indexes.py new file mode 100644 index 0000000..7f1dfac --- /dev/null +++ b/blog/search_indexes.py @@ -0,0 +1,13 @@ +from haystack import indexes + +from blog.models import Article + + +class ArticleIndex(indexes.SearchIndex, indexes.Indexable): + text = indexes.CharField(document=True, use_template=True) + + def get_model(self): + return Article + + def index_queryset(self, using=None): + return self.get_model().objects.filter(status='p') diff --git a/blog/templatetags/__init__.py b/blog/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/templatetags/blog_tags.py b/blog/templatetags/blog_tags.py new file mode 100644 index 0000000..d6cd5d5 --- /dev/null +++ b/blog/templatetags/blog_tags.py @@ -0,0 +1,344 @@ +import hashlib +import logging +import random +import urllib + +from django import template +from django.conf import settings +from django.db.models import Q +from django.shortcuts import get_object_or_404 +from django.template.defaultfilters import stringfilter +from django.templatetags.static import static +from django.urls import reverse +from django.utils.safestring import mark_safe + +from blog.models import Article, Category, Tag, Links, SideBar, LinkShowType +from comments.models import Comment +from djangoblog.utils import CommonMarkdown, sanitize_html +from djangoblog.utils import cache +from djangoblog.utils import get_current_site +from oauth.models import OAuthUser +from djangoblog.plugin_manage import hooks + +logger = logging.getLogger(__name__) + +register = template.Library() + + +@register.simple_tag(takes_context=True) +def head_meta(context): + return mark_safe(hooks.apply_filters('head_meta', '', context)) + + +@register.simple_tag +def timeformat(data): + try: + return data.strftime(settings.TIME_FORMAT) + except Exception as e: + logger.error(e) + return "" + + +@register.simple_tag +def datetimeformat(data): + try: + return data.strftime(settings.DATE_TIME_FORMAT) + except Exception as e: + logger.error(e) + return "" + + +@register.filter() +@stringfilter +def custom_markdown(content): + return mark_safe(CommonMarkdown.get_markdown(content)) + + +@register.simple_tag +def get_markdown_toc(content): + from djangoblog.utils import CommonMarkdown + body, toc = CommonMarkdown.get_markdown_with_toc(content) + return mark_safe(toc) + + +@register.filter() +@stringfilter +def comment_markdown(content): + content = CommonMarkdown.get_markdown(content) + return mark_safe(sanitize_html(content)) + + +@register.filter(is_safe=True) +@stringfilter +def truncatechars_content(content): + """ + 获得文章内容的摘要 + :param content: + :return: + """ + from django.template.defaultfilters import truncatechars_html + from djangoblog.utils import get_blog_setting + blogsetting = get_blog_setting() + return truncatechars_html(content, blogsetting.article_sub_length) + + +@register.filter(is_safe=True) +@stringfilter +def truncate(content): + from django.utils.html import strip_tags + + return strip_tags(content)[:150] + + +@register.inclusion_tag('blog/tags/breadcrumb.html') +def load_breadcrumb(article): + """ + 获得文章面包屑 + :param article: + :return: + """ + names = article.get_category_tree() + from djangoblog.utils import get_blog_setting + blogsetting = get_blog_setting() + site = get_current_site().domain + names.append((blogsetting.site_name, '/')) + names = names[::-1] + + return { + 'names': names, + 'title': article.title, + 'count': len(names) + 1 + } + + +@register.inclusion_tag('blog/tags/article_tag_list.html') +def load_articletags(article): + """ + 文章标签 + :param article: + :return: + """ + tags = article.tags.all() + tags_list = [] + for tag in tags: + url = tag.get_absolute_url() + count = tag.get_article_count() + tags_list.append(( + url, count, tag, random.choice(settings.BOOTSTRAP_COLOR_TYPES) + )) + return { + 'article_tags_list': tags_list + } + + +@register.inclusion_tag('blog/tags/sidebar.html') +def load_sidebar(user, linktype): + """ + 加载侧边栏 + :return: + """ + value = cache.get("sidebar" + linktype) + if value: + value['user'] = user + return value + else: + 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] + 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] + dates = Article.objects.datetimes('creation_time', 'month', order='DESC') + links = Links.objects.filter(is_enable=True).filter( + Q(show_type=str(linktype)) | Q(show_type=LinkShowType.A)) + commment_list = Comment.objects.filter(is_enable=True).order_by( + '-id')[:blogsetting.sidebar_comment_count] + # 标签云 计算字体大小 + # 根据总数计算出平均值 大小为 (数目/平均值)*步长 + increment = 5 + tags = Tag.objects.all() + sidebar_tags = None + if tags and len(tags) > 0: + s = [t for t in [(t, t.get_article_count()) for t in tags] if t[1]] + 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)) + random.shuffle(sidebar_tags) + + value = { + 'recent_articles': recent_articles, + 'sidebar_categorys': sidebar_categorys, + 'most_read_articles': most_read_articles, + 'article_dates': dates, + 'sidebar_comments': commment_list, + 'sidabar_links': links, + 'show_google_adsense': blogsetting.show_google_adsense, + 'google_adsense_codes': blogsetting.google_adsense_codes, + 'open_site_comment': blogsetting.open_site_comment, + 'show_gongan_code': blogsetting.show_gongan_code, + 'sidebar_tags': sidebar_tags, + 'extra_sidebars': extra_sidebars + } + cache.set("sidebar" + linktype, value, 60 * 60 * 60 * 3) + logger.info('set sidebar cache.key:{key}'.format(key="sidebar" + linktype)) + value['user'] = user + return value + + +@register.inclusion_tag('blog/tags/article_meta_info.html') +def load_article_metas(article, user): + """ + 获得文章meta信息 + :param article: + :return: + """ + return { + 'article': article, + 'user': user + } + + +@register.inclusion_tag('blog/tags/article_pagination.html') +def load_pagination_info(page_obj, page_type, tag_name): + previous_url = '' + next_url = '' + if page_type == '': + if page_obj.has_next(): + next_number = page_obj.next_page_number() + 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}) + 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}) + 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}) + 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}) + 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}) + + 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}) + 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}) + + return { + 'previous_url': previous_url, + 'next_url': next_url, + 'page_obj': page_obj + } + + +@register.inclusion_tag('blog/tags/article_info.html') +def load_article_detail(article, isindex, user): + """ + 加载文章详情 + :param article: + :param isindex:是否列表页,若是列表页只显示摘要 + :return: + """ + from djangoblog.utils import get_blog_setting + blogsetting = get_blog_setting() + + return { + 'article': article, + 'isindex': isindex, + 'user': user, + 'open_site_comment': blogsetting.open_site_comment, + } + + +# return only the URL of the gravatar +# TEMPLATE USE: {{ email|gravatar_url:150 }} +@register.filter +def gravatar_url(email, size=40): + """获得gravatar头像""" + cachekey = 'gravatat/' + email + url = cache.get(cachekey) + if url: + return url + else: + usermodels = OAuthUser.objects.filter(email=email) + if usermodels: + o = list(filter(lambda x: x.picture is not None, usermodels)) + if o: + return o[0].picture + email = email.encode('utf-8') + + default = static('blog/img/avatar.png') + + 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) + logger.info('set gravatar cache.key:{key}'.format(key=cachekey)) + return url + + +@register.filter +def gravatar(email, size=40): + """获得gravatar头像""" + url = gravatar_url(email, size) + return mark_safe( + '' % + (url, size, size)) + + +@register.simple_tag +def query(qs, **kwargs): + """ template tag which allows queryset filtering. Usage: + {% query books author=author as mybooks %} + {% for book in mybooks %} + ... + {% endfor %} + """ + return qs.filter(**kwargs) + + +@register.filter +def addstr(arg1, arg2): + """concatenate arg1 & arg2""" + return str(arg1) + str(arg2) diff --git a/blog/tests.py b/blog/tests.py new file mode 100644 index 0000000..ee13505 --- /dev/null +++ b/blog/tests.py @@ -0,0 +1,232 @@ +import os + +from django.conf import settings +from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.management import call_command +from django.core.paginator import Paginator +from django.templatetags.static import static +from django.test import Client, RequestFactory, TestCase +from django.urls import reverse +from django.utils import timezone + +from accounts.models import BlogUser +from blog.forms import BlogSearchForm +from blog.models import Article, Category, Tag, SideBar, Links +from blog.templatetags.blog_tags import load_pagination_info, load_articletags +from djangoblog.utils import get_current_site, get_sha256 +from oauth.models import OAuthUser, OAuthConfig + + +# Create your tests here. + +class ArticleTest(TestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + + def test_validate_article(self): + site = get_current_site().domain + 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 + user.save() + response = self.client.get(user.get_absolute_url()) + self.assertEqual(response.status_code, 200) + response = self.client.get('/admin/servermanager/emailsendlog/') + response = self.client.get('admin/admin/logentry/') + s = SideBar() + s.sequence = 1 + s.name = 'test' + s.content = 'test content' + s.is_enable = True + s.save() + + category = Category() + category.name = "category" + category.creation_time = timezone.now() + category.last_mod_time = timezone.now() + category.save() + + tag = Tag() + tag.name = "nicetag" + tag.save() + + article = Article() + article.title = "nicetitle" + article.body = "nicecontent" + article.author = user + article.category = category + article.type = 'a' + article.status = 'p' + + article.save() + self.assertEqual(0, article.tags.count()) + article.tags.add(tag) + article.save() + self.assertEqual(1, article.tags.count()) + + for i in range(20): + article = Article() + article.title = "nicetitle" + str(i) + article.body = "nicetitle" + str(i) + article.author = user + article.category = category + article.type = 'a' + article.status = 'p' + article.save() + article.tags.add(tag) + article.save() + from blog.documents import ELASTICSEARCH_ENABLED + if ELASTICSEARCH_ENABLED: + call_command("build_index") + response = self.client.get('/search', {'q': 'nicetitle'}) + self.assertEqual(response.status_code, 200) + + response = self.client.get(article.get_absolute_url()) + self.assertEqual(response.status_code, 200) + from djangoblog.spider_notify import SpiderNotify + SpiderNotify.notify(article.get_absolute_url()) + response = self.client.get(tag.get_absolute_url()) + self.assertEqual(response.status_code, 200) + + response = self.client.get(category.get_absolute_url()) + self.assertEqual(response.status_code, 200) + + response = self.client.get('/search', {'q': 'django'}) + self.assertEqual(response.status_code, 200) + s = load_articletags(article) + self.assertIsNotNone(s) + + self.client.login(username='liangliangyy', password='liangliangyy') + + response = self.client.get(reverse('blog:archives')) + self.assertEqual(response.status_code, 200) + + p = Paginator(Article.objects.all(), settings.PAGINATE_BY) + self.check_pagination(p, '', '') + + p = Paginator(Article.objects.filter(tags=tag), settings.PAGINATE_BY) + self.check_pagination(p, '分类标签归档', tag.slug) + + p = Paginator( + Article.objects.filter( + author__username='liangliangyy'), settings.PAGINATE_BY) + self.check_pagination(p, '作者文章归档', 'liangliangyy') + + p = Paginator(Article.objects.filter(category=category), settings.PAGINATE_BY) + self.check_pagination(p, '分类目录归档', category.slug) + + f = BlogSearchForm() + f.search() + # self.client.login(username='liangliangyy', password='liangliangyy') + from djangoblog.spider_notify import SpiderNotify + SpiderNotify.baidu_notify([article.get_full_url()]) + + from blog.templatetags.blog_tags import gravatar_url, gravatar + u = gravatar_url('liangliangyy@gmail.com') + u = gravatar('liangliangyy@gmail.com') + + 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) + + response = self.client.get('/feed/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/sitemap.xml') + self.assertEqual(response.status_code, 200) + + self.client.get("/admin/blog/article/1/delete/") + self.client.get('/admin/servermanager/emailsendlog/') + self.client.get('/admin/admin/logentry/') + self.client.get('/admin/admin/logentry/1/change/') + + def check_pagination(self, p, type, value): + for page in range(1, p.num_pages + 1): + s = load_pagination_info(p.page(page), type, value) + self.assertIsNotNone(s) + if s['previous_url']: + response = self.client.get(s['previous_url']) + self.assertEqual(response.status_code, 200) + if s['next_url']: + response = self.client.get(s['next_url']) + self.assertEqual(response.status_code, 200) + + def test_image(self): + import requests + rsp = requests.get( + 'https://www.python.org/static/img/python-logo.png') + imagepath = os.path.join(settings.BASE_DIR, 'python.png') + with open(imagepath, 'wb') as file: + file.write(rsp.content) + rsp = self.client.post('/upload') + self.assertEqual(rsp.status_code, 403) + sign = get_sha256(get_sha256(settings.SECRET_KEY)) + with open(imagepath, 'rb') as file: + 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) + self.assertEqual(rsp.status_code, 200) + os.remove(imagepath) + 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.png') + + def test_errorpage(self): + rsp = self.client.get('/eee') + self.assertEqual(rsp.status_code, 404) + + def test_commands(self): + 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 + user.save() + + c = OAuthConfig() + c.type = 'qq' + c.appkey = 'appkey' + c.appsecret = 'appsecret' + c.save() + + u = OAuthUser() + u.type = 'qq' + u.openid = 'openid' + u.user = user + u.picture = static("/blog/img/avatar.png") + u.metadata = ''' +{ +"figureurl": "https://qzapp.qlogo.cn/qzapp/101513904/C740E30B4113EAA80E0D9918ABC78E82/30" +}''' + u.save() + + u = OAuthUser() + u.type = 'qq' + u.openid = 'openid1' + u.picture = 'https://qzapp.qlogo.cn/qzapp/101513904/C740E30B4113EAA80E0D9918ABC78E82/30' + u.metadata = ''' + { + "figureurl": "https://qzapp.qlogo.cn/qzapp/101513904/C740E30B4113EAA80E0D9918ABC78E82/30" + }''' + u.save() + + from blog.documents import ELASTICSEARCH_ENABLED + if ELASTICSEARCH_ENABLED: + call_command("build_index") + call_command("ping_baidu", "all") + call_command("create_testdata") + call_command("clear_cache") + call_command("sync_user_avatar") + call_command("build_search_words") diff --git a/blog/urls.py b/blog/urls.py new file mode 100644 index 0000000..adf2703 --- /dev/null +++ b/blog/urls.py @@ -0,0 +1,62 @@ +from django.urls import path +from django.views.decorators.cache import cache_page + +from . import views + +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'clean', + views.clean_cache_view, + name='clean'), +] diff --git a/blog/views.py b/blog/views.py new file mode 100644 index 0000000..d5dc7ec --- /dev/null +++ b/blog/views.py @@ -0,0 +1,379 @@ +import logging +import os +import uuid + +from django.conf import settings +from django.core.paginator import Paginator +from django.http import HttpResponse, HttpResponseForbidden +from django.shortcuts import get_object_or_404 +from django.shortcuts import render +from django.templatetags.static import static +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from django.views.decorators.csrf import csrf_exempt +from django.views.generic.detail import DetailView +from django.views.generic.list import ListView +from haystack.views import SearchView + +from blog.models import Article, Category, LinkShowType, Links, Tag +from comments.forms import CommentForm +from djangoblog.plugin_manage import hooks +from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME +from djangoblog.utils import cache, get_blog_setting, get_sha256 + +logger = logging.getLogger(__name__) + + +class ArticleListView(ListView): + # template_name属性用于指定使用哪个模板进行渲染 + template_name = 'blog/article_index.html' + + # context_object_name属性用于给上下文变量取名(在模板中使用该名字) + context_object_name = 'article_list' + + # 页面类型,分类目录或标签列表等 + page_type = '' + paginate_by = settings.PAGINATE_BY + page_kwarg = 'page' + link_type = LinkShowType.L + + def get_view_cache_key(self): + return self.request.get['pages'] + + @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 + return page + + def get_queryset_cache_key(self): + """ + 子类重写.获得queryset的缓存key + """ + raise NotImplementedError() + + def get_queryset_data(self): + """ + 子类重写.获取queryset的数据 + """ + raise NotImplementedError() + + def get_queryset_from_cache(self, cache_key): + ''' + 缓存页面数据 + :param cache_key: 缓存key + :return: + ''' + value = cache.get(cache_key) + if value: + logger.info('get view cache.key:{key}'.format(key=cache_key)) + return value + else: + article_list = self.get_queryset_data() + cache.set(cache_key, article_list) + logger.info('set view cache.key:{key}'.format(key=cache_key)) + return article_list + + def get_queryset(self): + ''' + 重写默认,从缓存获取数据 + :return: + ''' + key = self.get_queryset_cache_key() + value = self.get_queryset_from_cache(key) + return value + + def get_context_data(self, **kwargs): + kwargs['linktype'] = self.link_type + return super(ArticleListView, self).get_context_data(**kwargs) + + +class IndexView(ArticleListView): + ''' + 首页 + ''' + # 友情链接类型 + link_type = LinkShowType.I + + def get_queryset_data(self): + article_list = Article.objects.filter(type='a', status='p') + return article_list + + def get_queryset_cache_key(self): + cache_key = 'index_{page}'.format(page=self.page_number) + return cache_key + + +class ArticleDetailView(DetailView): + ''' + 文章详情页面 + ''' + template_name = 'blog/article_detail.html' + model = Article + pk_url_kwarg = 'article_id' + context_object_name = "article" + + def get_context_data(self, **kwargs): + comment_form = CommentForm() + + article_comments = self.object.comment_list() + parent_comments = article_comments.filter(parent_comment=None) + blog_setting = get_blog_setting() + paginator = Paginator(parent_comments, blog_setting.article_comment_count) + page = self.request.GET.get('comment_page', '1') + if not page.isnumeric(): + page = 1 + else: + page = int(page) + if page < 1: + page = 1 + if page > paginator.num_pages: + page = paginator.num_pages + + p_comments = paginator.page(page) + next_page = p_comments.next_page_number() if p_comments.has_next() else None + prev_page = p_comments.previous_page_number() if p_comments.has_previous() else None + + if next_page: + kwargs[ + 'comment_next_page_url'] = self.object.get_absolute_url() + f'?comment_page={next_page}#commentlist-container' + if prev_page: + kwargs[ + 'comment_prev_page_url'] = self.object.get_absolute_url() + f'?comment_page={prev_page}#commentlist-container' + kwargs['form'] = comment_form + kwargs['article_comments'] = article_comments + kwargs['p_comments'] = p_comments + 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 + + context = super(ArticleDetailView, self).get_context_data(**kwargs) + article = self.object + # Action Hook, 通知插件"文章详情已获取" + hooks.run_action('after_article_body_get', article=article, request=self.request) + # # Filter Hook, 允许插件修改文章正文 + article.body = hooks.apply_filters(ARTICLE_CONTENT_HOOK_NAME, article.body, article=article, + request=self.request) + + return context + + +class CategoryDetailView(ArticleListView): + ''' + 分类目录列表 + ''' + page_type = "分类目录归档" + + def get_queryset_data(self): + slug = self.kwargs['category_name'] + category = get_object_or_404(Category, slug=slug) + + 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') + return article_list + + def get_queryset_cache_key(self): + slug = self.kwargs['category_name'] + 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) + return cache_key + + def get_context_data(self, **kwargs): + + categoryname = self.categoryname + try: + categoryname = categoryname.split('/')[-1] + except BaseException: + pass + kwargs['page_type'] = CategoryDetailView.page_type + kwargs['tag_name'] = categoryname + return super(CategoryDetailView, self).get_context_data(**kwargs) + + +class AuthorDetailView(ArticleListView): + ''' + 作者详情页 + ''' + page_type = '作者文章归档' + + def get_queryset_cache_key(self): + from uuslug import slugify + author_name = slugify(self.kwargs['author_name']) + 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') + return article_list + + def get_context_data(self, **kwargs): + author_name = self.kwargs['author_name'] + kwargs['page_type'] = AuthorDetailView.page_type + kwargs['tag_name'] = author_name + return super(AuthorDetailView, self).get_context_data(**kwargs) + + +class TagDetailView(ArticleListView): + ''' + 标签列表页面 + ''' + page_type = '分类标签归档' + + def get_queryset_data(self): + slug = self.kwargs['tag_name'] + 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') + return article_list + + def get_queryset_cache_key(self): + slug = self.kwargs['tag_name'] + 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) + return cache_key + + def get_context_data(self, **kwargs): + # tag_name = self.kwargs['tag_name'] + tag_name = self.name + kwargs['page_type'] = TagDetailView.page_type + kwargs['tag_name'] = tag_name + return super(TagDetailView, self).get_context_data(**kwargs) + + +class ArchivesView(ArticleListView): + ''' + 文章归档页面 + ''' + page_type = '文章归档' + paginate_by = None + page_kwarg = None + template_name = 'blog/article_archives.html' + + def get_queryset_data(self): + return Article.objects.filter(status='p').all() + + def get_queryset_cache_key(self): + cache_key = 'archives' + return cache_key + + +class LinkListView(ListView): + model = Links + template_name = 'blog/links_list.html' + + def get_queryset(self): + return Links.objects.filter(is_enable=True) + + +class EsSearchView(SearchView): + def get_context(self): + paginator, page = self.build_page() + context = { + "query": self.query, + "form": self.form, + "page": page, + "paginator": paginator, + "suggestion": None, + } + if hasattr(self.results, "query") and self.results.query.backend.include_spelling: + context["suggestion"] = self.results.query.get_spelling_suggestion() + context.update(self.extra_context()) + + return context + + +@csrf_exempt +def fileupload(request): + """ + 该方法需自己写调用端来上传图片,该方法仅提供图床功能 + :param request: + :return: + """ + if request.method == 'POST': + sign = request.GET.get('sign', None) + if not sign: + return HttpResponseForbidden() + if not sign == get_sha256(get_sha256(settings.SECRET_KEY)): + return HttpResponseForbidden() + response = [] + for filename in request.FILES: + timestr = timezone.now().strftime('%Y/%m/%d') + imgextensions = ['jpg', 'png', 'jpeg', 'bmp'] + fname = u''.join(str(filename)) + isimage = len([i for i in imgextensions if fname.find(i) >= 0]) > 0 + base_dir = os.path.join(settings.STATICFILES, "files" if not isimage else "image", timestr) + if not os.path.exists(base_dir): + os.makedirs(base_dir) + savepath = os.path.normpath(os.path.join(base_dir, f"{uuid.uuid4().hex}{os.path.splitext(filename)[-1]}")) + if not savepath.startswith(base_dir): + return HttpResponse("only for post") + with open(savepath, 'wb+') as wfile: + for chunk in request.FILES[filename].chunks(): + wfile.write(chunk) + if isimage: + from PIL import Image + image = Image.open(savepath) + image.save(savepath, quality=20, optimize=True) + url = static(savepath) + response.append(url) + return HttpResponse(response) + + else: + return HttpResponse("only for post") + + +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': _('Sorry, the page you requested is not found, please click the home page to see other?'), + 'statuscode': '404'}, + status=404) + + +def server_error_view(request, template_name='blog/error_page.html'): + return render(request, + template_name, + {'message': _('Sorry, the server is busy, please click the home page to see other?'), + 'statuscode': '500'}, + status=500) + + +def permission_denied_view( + request, + exception, + template_name='blog/error_page.html'): + if exception: + logger.error(exception) + return render( + request, template_name, { + 'message': _('Sorry, you do not have permission to access this page?'), + 'statuscode': '403'}, status=403) + + +def clean_cache_view(request): + cache.clear() + return HttpResponse('ok') diff --git a/comments/__init__.py b/comments/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comments/admin.py b/comments/admin.py new file mode 100644 index 0000000..a814f3f --- /dev/null +++ b/comments/admin.py @@ -0,0 +1,47 @@ +from django.contrib import admin +from django.urls import reverse +from django.utils.html import format_html +from django.utils.translation import gettext_lazy as _ + + +def disable_commentstatus(modeladmin, request, queryset): + queryset.update(is_enable=False) + + +def enable_commentstatus(modeladmin, request, queryset): + queryset.update(is_enable=True) + + +disable_commentstatus.short_description = _('Disable comments') +enable_commentstatus.short_description = _('Enable comments') + + +class CommentAdmin(admin.ModelAdmin): + list_per_page = 20 + list_display = ( + 'id', + 'body', + 'link_to_userinfo', + 'link_to_article', + 'is_enable', + 'creation_time') + list_display_links = ('id', 'body', 'is_enable') + list_filter = ('is_enable',) + exclude = ('creation_time', 'last_modify_time') + actions = [disable_commentstatus, enable_commentstatus] + + def link_to_userinfo(self, obj): + 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)) + + def link_to_article(self, obj): + info = (obj.article._meta.app_label, obj.article._meta.model_name) + link = reverse('admin:%s_%s_change' % info, args=(obj.article.id,)) + return format_html( + u'%s' % (link, obj.article.title)) + + link_to_userinfo.short_description = _('User') + link_to_article.short_description = _('Article') diff --git a/comments/apps.py b/comments/apps.py new file mode 100644 index 0000000..ff01b77 --- /dev/null +++ b/comments/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CommentsConfig(AppConfig): + name = 'comments' diff --git a/comments/forms.py b/comments/forms.py new file mode 100644 index 0000000..e83737d --- /dev/null +++ b/comments/forms.py @@ -0,0 +1,13 @@ +from django import forms +from django.forms import ModelForm + +from .models import Comment + + +class CommentForm(ModelForm): + parent_comment_id = forms.IntegerField( + widget=forms.HiddenInput, required=False) + + class Meta: + model = Comment + fields = ['body'] diff --git a/comments/migrations/0001_initial.py b/comments/migrations/0001_initial.py new file mode 100644 index 0000000..61d1e53 --- /dev/null +++ b/comments/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('blog', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('body', models.TextField(max_length=300, verbose_name='正文')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='文章')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), + ('parent_comment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='上级评论')), + ], + options={ + 'verbose_name': '评论', + 'verbose_name_plural': '评论', + 'ordering': ['-id'], + 'get_latest_by': 'id', + }, + ), + ] diff --git a/comments/migrations/0002_alter_comment_is_enable.py b/comments/migrations/0002_alter_comment_is_enable.py new file mode 100644 index 0000000..17c44db --- /dev/null +++ b/comments/migrations/0002_alter_comment_is_enable.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.7 on 2023-04-24 13:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('comments', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='is_enable', + field=models.BooleanField(default=False, verbose_name='是否显示'), + ), + ] diff --git a/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py b/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py new file mode 100644 index 0000000..a1ca970 --- /dev/null +++ b/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py @@ -0,0 +1,60 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:13 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('blog', '0005_alter_article_options_alter_category_options_and_more'), + ('comments', '0002_alter_comment_is_enable'), + ] + + operations = [ + migrations.AlterModelOptions( + name='comment', + options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'comment', 'verbose_name_plural': 'comment'}, + ), + migrations.RemoveField( + model_name='comment', + name='created_time', + ), + migrations.RemoveField( + model_name='comment', + name='last_mod_time', + ), + migrations.AddField( + model_name='comment', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='comment', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'), + ), + migrations.AlterField( + model_name='comment', + name='article', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='article'), + ), + migrations.AlterField( + model_name='comment', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'), + ), + migrations.AlterField( + model_name='comment', + name='is_enable', + field=models.BooleanField(default=False, verbose_name='enable'), + ), + migrations.AlterField( + model_name='comment', + name='parent_comment', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='parent comment'), + ), + ] diff --git a/comments/migrations/__init__.py b/comments/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comments/models.py b/comments/models.py new file mode 100644 index 0000000..7c3bbc8 --- /dev/null +++ b/comments/models.py @@ -0,0 +1,39 @@ +from django.conf import settings +from django.db import models +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ + +from blog.models import Article + + +# Create your models here. + +class Comment(models.Model): + body = models.TextField('正文', max_length=300) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_modify_time = models.DateTimeField(_('last modify time'), default=now) + author = models.ForeignKey( + settings.AUTH_USER_MODEL, + verbose_name=_('author'), + on_delete=models.CASCADE) + article = models.ForeignKey( + Article, + verbose_name=_('article'), + on_delete=models.CASCADE) + parent_comment = models.ForeignKey( + 'self', + verbose_name=_('parent comment'), + blank=True, + null=True, + on_delete=models.CASCADE) + is_enable = models.BooleanField(_('enable'), + default=False, blank=False, null=False) + + class Meta: + ordering = ['-id'] + verbose_name = _('comment') + verbose_name_plural = verbose_name + get_latest_by = 'id' + + def __str__(self): + return self.body diff --git a/comments/templatetags/__init__.py b/comments/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comments/templatetags/comments_tags.py b/comments/templatetags/comments_tags.py new file mode 100644 index 0000000..fde02b4 --- /dev/null +++ b/comments/templatetags/comments_tags.py @@ -0,0 +1,30 @@ +from django import template + +register = template.Library() + + +@register.simple_tag +def parse_commenttree(commentlist, comment): + """获得当前评论子评论的列表 + 用法: {% parse_commenttree article_comments comment as childcomments %} + """ + datas = [] + + def parse(c): + childs = commentlist.filter(parent_comment=c, is_enable=True) + for child in childs: + datas.append(child) + parse(child) + + parse(comment) + return datas + + +@register.inclusion_tag('comments/tags/comment_item.html') +def show_comment_item(comment, ischild): + """评论""" + depth = 1 if ischild else 2 + return { + 'comment_item': comment, + 'depth': depth + } diff --git a/comments/tests.py b/comments/tests.py new file mode 100644 index 0000000..2a7f55f --- /dev/null +++ b/comments/tests.py @@ -0,0 +1,109 @@ +from django.test import Client, RequestFactory, TransactionTestCase +from django.urls import reverse + +from accounts.models import BlogUser +from blog.models import Category, Article +from comments.models import Comment +from comments.templatetags.comments_tags import * +from djangoblog.utils import get_max_articleid_commentid + + +# Create your tests here. + +class CommentsTest(TransactionTestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + from blog.models import BlogSettings + value = BlogSettings() + value.comment_need_review = True + value.save() + + self.user = BlogUser.objects.create_superuser( + email="liangliangyy1@gmail.com", + username="liangliangyy1", + password="liangliangyy1") + + def update_article_comment_status(self, article): + comments = article.comment_set.all() + for comment in comments: + comment.is_enable = True + comment.save() + + def test_validate_comment(self): + self.client.login(username='liangliangyy1', password='liangliangyy1') + + category = Category() + category.name = "categoryccc" + category.save() + + article = Article() + article.title = "nicetitleccc" + article.body = "nicecontentccc" + article.author = self.user + article.category = category + article.type = 'a' + article.status = 'p' + article.save() + + comment_url = reverse( + 'comments:postcomment', kwargs={ + 'article_id': article.id}) + + response = self.client.post(comment_url, + { + 'body': '123ffffffffff' + }) + + self.assertEqual(response.status_code, 302) + + article = Article.objects.get(pk=article.pk) + self.assertEqual(len(article.comment_list()), 0) + self.update_article_comment_status(article) + + self.assertEqual(len(article.comment_list()), 1) + + response = self.client.post(comment_url, + { + 'body': '123ffffffffff', + }) + + self.assertEqual(response.status_code, 302) + + article = Article.objects.get(pk=article.pk) + self.update_article_comment_status(article) + self.assertEqual(len(article.comment_list()), 2) + parent_comment_id = article.comment_list()[0].id + + response = self.client.post(comment_url, + { + 'body': ''' + # Title1 + + ```python + import os + ``` + + [url](https://www.lylinux.net/) + + [ddd](http://www.baidu.com) + + + ''', + 'parent_comment_id': parent_comment_id + }) + + self.assertEqual(response.status_code, 302) + self.update_article_comment_status(article) + article = Article.objects.get(pk=article.pk) + self.assertEqual(len(article.comment_list()), 3) + comment = Comment.objects.get(id=parent_comment_id) + tree = parse_commenttree(article.comment_list(), comment) + self.assertEqual(len(tree), 1) + data = show_comment_item(comment, True) + self.assertIsNotNone(data) + s = get_max_articleid_commentid() + self.assertIsNotNone(s) + + from comments.utils import send_comment_email + send_comment_email(comment) diff --git a/comments/urls.py b/comments/urls.py new file mode 100644 index 0000000..7df3fab --- /dev/null +++ b/comments/urls.py @@ -0,0 +1,11 @@ +from django.urls import path + +from . import views + +app_name = "comments" +urlpatterns = [ + path( + 'article//postcomment', + views.CommentPostView.as_view(), + name='postcomment'), +] diff --git a/comments/utils.py b/comments/utils.py new file mode 100644 index 0000000..f01dba7 --- /dev/null +++ b/comments/utils.py @@ -0,0 +1,38 @@ +import logging + +from django.utils.translation import gettext_lazy as _ + +from djangoblog.utils import get_current_site +from djangoblog.utils import send_email + +logger = logging.getLogger(__name__) + + +def send_comment_email(comment): + site = get_current_site().domain + subject = _('Thanks for your comment') + article_url = f"https://{site}{comment.article.get_absolute_url()}" + html_content = _("""

Thank you very much for your comments on this site

+ You can visit %(article_title)s + to review your comments, + Thank you again! +
+ If the link above cannot be opened, please copy this link to your browser. + %(article_url)s""") % {'article_url': article_url, 'article_title': comment.article.title} + tomail = comment.author.email + send_email([tomail], subject, html_content) + try: + if comment.parent_comment: + html_content = _("""Your comment on %(article_title)s
has + received a reply.
%(comment_body)s +
+ go check it out! +
+ If the link above cannot be opened, please copy this link to your browser. + %(article_url)s + """) % {'article_url': article_url, 'article_title': comment.article.title, + 'comment_body': comment.parent_comment.body} + tomail = comment.parent_comment.author.email + send_email([tomail], subject, html_content) + except Exception as e: + logger.error(e) diff --git a/comments/views.py b/comments/views.py new file mode 100644 index 0000000..ad9b2b9 --- /dev/null +++ b/comments/views.py @@ -0,0 +1,63 @@ +# Create your views here. +from django.core.exceptions import ValidationError +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.utils.decorators import method_decorator +from django.views.decorators.csrf import csrf_protect +from django.views.generic.edit import FormView + +from accounts.models import BlogUser +from blog.models import Article +from .forms import CommentForm +from .models import Comment + + +class CommentPostView(FormView): + form_class = CommentForm + template_name = 'blog/article_detail.html' + + @method_decorator(csrf_protect) + def dispatch(self, *args, **kwargs): + return super(CommentPostView, self).dispatch(*args, **kwargs) + + def get(self, request, *args, **kwargs): + article_id = self.kwargs['article_id'] + article = get_object_or_404(Article, pk=article_id) + url = article.get_absolute_url() + return HttpResponseRedirect(url + "#comments") + + def form_invalid(self, form): + article_id = self.kwargs['article_id'] + article = get_object_or_404(Article, pk=article_id) + + return self.render_to_response({ + 'form': form, + 'article': article + }) + + def form_valid(self, form): + """提交的数据验证合法后的逻辑""" + user = self.request.user + author = BlogUser.objects.get(pk=user.pk) + article_id = self.kwargs['article_id'] + article = get_object_or_404(Article, pk=article_id) + + if article.comment_status == 'c' or article.status == 'c': + raise ValidationError("该文章评论已关闭.") + comment = form.save(False) + comment.article = article + from djangoblog.utils import get_blog_setting + settings = get_blog_setting() + if not settings.comment_need_review: + comment.is_enable = True + comment.author = author + + if 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)) diff --git a/deploy/docker-compose/docker-compose.es.yml b/deploy/docker-compose/docker-compose.es.yml new file mode 100644 index 0000000..83e35ff --- /dev/null +++ b/deploy/docker-compose/docker-compose.es.yml @@ -0,0 +1,48 @@ +version: '3' + +services: + es: + image: liangliangyy/elasticsearch-analysis-ik:8.6.1 + container_name: es + restart: always + environment: + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ports: + - 9200:9200 + volumes: + - ./bin/datas/es/:/usr/share/elasticsearch/data/ + + kibana: + image: kibana:8.6.1 + restart: always + container_name: kibana + ports: + - 5601:5601 + environment: + - ELASTICSEARCH_HOSTS=http://es:9200 + + djangoblog: + build: . + restart: always + command: bash -c 'sh /code/djangoblog/bin/docker_start.sh' + ports: + - "8000:8000" + volumes: + - ./collectedstatic:/code/djangoblog/collectedstatic + - ./uploads:/code/djangoblog/uploads + environment: + - DJANGO_MYSQL_DATABASE=djangoblog + - DJANGO_MYSQL_USER=root + - DJANGO_MYSQL_PASSWORD=DjAnGoBlOg!2!Q@W#E + - DJANGO_MYSQL_HOST=db + - DJANGO_MYSQL_PORT=3306 + - DJANGO_MEMCACHED_LOCATION=memcached:11211 + - DJANGO_ELASTICSEARCH_HOST=es:9200 + links: + - db + - memcached + depends_on: + - db + container_name: djangoblog + diff --git a/deploy/docker-compose/docker-compose.yml b/deploy/docker-compose/docker-compose.yml new file mode 100644 index 0000000..9609af3 --- /dev/null +++ b/deploy/docker-compose/docker-compose.yml @@ -0,0 +1,60 @@ +version: '3' + +services: + db: + image: mysql:latest + restart: always + environment: + - MYSQL_DATABASE=djangoblog + - MYSQL_ROOT_PASSWORD=DjAnGoBlOg!2!Q@W#E + ports: + - 3306:3306 + volumes: + - ./bin/datas/mysql/:/var/lib/mysql + depends_on: + - redis + container_name: db + + djangoblog: + build: + context: ../../ + restart: always + command: bash -c 'sh /code/djangoblog/bin/docker_start.sh' + ports: + - "8000:8000" + volumes: + - ./collectedstatic:/code/djangoblog/collectedstatic + - ./logs:/code/djangoblog/logs + - ./uploads:/code/djangoblog/uploads + environment: + - DJANGO_MYSQL_DATABASE=djangoblog + - DJANGO_MYSQL_USER=root + - DJANGO_MYSQL_PASSWORD=DjAnGoBlOg!2!Q@W#E + - DJANGO_MYSQL_HOST=db + - DJANGO_MYSQL_PORT=3306 + - DJANGO_REDIS_URL=redis:6379 + links: + - db + - redis + depends_on: + - db + container_name: djangoblog + nginx: + restart: always + image: nginx:latest + ports: + - "80:80" + - "443:443" + volumes: + - ./bin/nginx.conf:/etc/nginx/nginx.conf + - ./collectedstatic:/code/djangoblog/collectedstatic + links: + - djangoblog:djangoblog + container_name: nginx + + redis: + restart: always + image: redis:latest + container_name: redis + ports: + - "6379:6379" diff --git a/deploy/entrypoint.sh b/deploy/entrypoint.sh new file mode 100644 index 0000000..2fb6491 --- /dev/null +++ b/deploy/entrypoint.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +NAME="djangoblog" +DJANGODIR=/code/djangoblog +USER=root +GROUP=root +NUM_WORKERS=1 +DJANGO_WSGI_MODULE=djangoblog.wsgi + + +echo "Starting $NAME as `whoami`" + +cd $DJANGODIR + +export PYTHONPATH=$DJANGODIR:$PYTHONPATH + +python manage.py makemigrations && \ + python manage.py migrate && \ + python manage.py collectstatic --noinput && \ + python manage.py compress --force && \ + python manage.py build_index && \ + python manage.py compilemessages || exit 1 + +exec gunicorn ${DJANGO_WSGI_MODULE}:application \ +--name $NAME \ +--workers $NUM_WORKERS \ +--user=$USER --group=$GROUP \ +--bind 0.0.0.0:8000 \ +--log-level=debug \ +--log-file=- \ +--worker-class gevent \ +--threads 4 diff --git a/deploy/k8s/configmap.yaml b/deploy/k8s/configmap.yaml new file mode 100644 index 0000000..835d4ad --- /dev/null +++ b/deploy/k8s/configmap.yaml @@ -0,0 +1,119 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: web-nginx-config + namespace: djangoblog +data: + nginx.conf: | + user nginx; + worker_processes auto; + error_log /var/log/nginx/error.log notice; + pid /var/run/nginx.pid; + + events { + worker_connections 1024; + multi_accept on; + use epoll; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + gzip on; + gzip_disable "msie6"; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 8; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; + + # Include server configurations + include /etc/nginx/conf.d/*.conf; + } + djangoblog.conf: | + server { + server_name lylinux.net; + root /code/djangoblog/collectedstatic/; + listen 80; + keepalive_timeout 70; + location /static/ { + expires max; + alias /code/djangoblog/collectedstatic/; + } + + location ~* (robots\.txt|ads\.txt|favicon\.ico|favion\.ico|crossdomain\.xml|google93fd32dbd906620a\.html|BingSiteAuth\.xml|baidu_verify_Ijeny6KrmS\.html)$ { + root /resource/djangopub; + expires 1d; + access_log off; + error_log off; + } + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + proxy_redirect off; + if (!-f $request_filename) { + proxy_pass http://djangoblog:8000; + break; + } + } + } + server { + server_name www.lylinux.net; + listen 80; + return 301 https://lylinux.net$request_uri; + } + resource.lylinux.net.conf: | + server { + index index.html index.htm; + server_name resource.lylinux.net; + root /resource/; + + location /djangoblog/ { + alias /code/djangoblog/collectedstatic/; + } + + access_log off; + error_log off; + include lylinux/resource.conf; + } + lylinux.resource.conf: | + expires max; + access_log off; + log_not_found off; + add_header Pragma public; + add_header Cache-Control "public"; + add_header "Access-Control-Allow-Origin" "*"; + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: djangoblog-env + namespace: djangoblog +data: + DJANGO_MYSQL_DATABASE: djangoblog + DJANGO_MYSQL_USER: db_user + DJANGO_MYSQL_PASSWORD: db_password + DJANGO_MYSQL_HOST: db_host + DJANGO_MYSQL_PORT: db_port + DJANGO_REDIS_URL: "redis:6379" + DJANGO_DEBUG: "False" + MYSQL_ROOT_PASSWORD: db_password + MYSQL_DATABASE: djangoblog + MYSQL_PASSWORD: db_password + DJANGO_SECRET_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + diff --git a/deploy/k8s/deployment.yaml b/deploy/k8s/deployment.yaml new file mode 100644 index 0000000..414fdcc --- /dev/null +++ b/deploy/k8s/deployment.yaml @@ -0,0 +1,274 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: djangoblog + namespace: djangoblog + labels: + app: djangoblog +spec: + replicas: 3 + selector: + matchLabels: + app: djangoblog + template: + metadata: + labels: + app: djangoblog + spec: + containers: + - name: djangoblog + image: liangliangyy/djangoblog:latest + imagePullPolicy: Always + ports: + - containerPort: 8000 + envFrom: + - configMapRef: + name: djangoblog-env + readinessProbe: + httpGet: + path: / + port: 8000 + initialDelaySeconds: 10 + periodSeconds: 30 + livenessProbe: + httpGet: + path: / + port: 8000 + initialDelaySeconds: 10 + periodSeconds: 30 + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: "2" + memory: 2Gi + volumeMounts: + - name: djangoblog + mountPath: /code/djangoblog/collectedstatic + - name: resource + mountPath: /resource + volumes: + - name: djangoblog + persistentVolumeClaim: + claimName: djangoblog-pvc + - name: resource + persistentVolumeClaim: + claimName: resource-pvc + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: djangoblog + labels: + app: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 6379 + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: 200m + memory: 2Gi + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: db + namespace: djangoblog + labels: + app: db +spec: + replicas: 1 + selector: + matchLabels: + app: db + template: + metadata: + labels: + app: db + spec: + containers: + - name: db + image: mysql:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 3306 + envFrom: + - configMapRef: + name: djangoblog-env + readinessProbe: + exec: + command: + - mysqladmin + - ping + - "-h" + - "127.0.0.1" + - "-u" + - "root" + - "-p$MYSQL_ROOT_PASSWORD" + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + exec: + command: + - mysqladmin + - ping + - "-h" + - "127.0.0.1" + - "-u" + - "root" + - "-p$MYSQL_ROOT_PASSWORD" + initialDelaySeconds: 10 + periodSeconds: 10 + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: "2" + memory: 2Gi + volumeMounts: + - name: db-data + mountPath: /var/lib/mysql + volumes: + - name: db-data + persistentVolumeClaim: + claimName: db-pvc + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + namespace: djangoblog + labels: + app: nginx +spec: + replicas: 1 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: "2" + memory: 2Gi + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: nginx-config + mountPath: /etc/nginx/conf.d/default.conf + subPath: djangoblog.conf + - name: nginx-config + mountPath: /etc/nginx/conf.d/resource.lylinux.net.conf + subPath: resource.lylinux.net.conf + - name: nginx-config + mountPath: /etc/nginx/lylinux/resource.conf + subPath: lylinux.resource.conf + - name: djangoblog-pvc + mountPath: /code/djangoblog/collectedstatic + - name: resource-pvc + mountPath: /resource + volumes: + - name: nginx-config + configMap: + name: web-nginx-config + - name: djangoblog-pvc + persistentVolumeClaim: + claimName: djangoblog-pvc + - name: resource-pvc + persistentVolumeClaim: + claimName: resource-pvc + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: elasticsearch + namespace: djangoblog + labels: + app: elasticsearch +spec: + replicas: 1 + selector: + matchLabels: + app: elasticsearch + template: + metadata: + labels: + app: elasticsearch + spec: + containers: + - name: elasticsearch + image: liangliangyy/elasticsearch-analysis-ik:8.6.1 + imagePullPolicy: IfNotPresent + env: + - name: discovery.type + value: single-node + - name: ES_JAVA_OPTS + value: "-Xms256m -Xmx256m" + - name: xpack.security.enabled + value: "false" + - name: xpack.monitoring.templates.enabled + value: "false" + ports: + - containerPort: 9200 + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: "2" + memory: 2Gi + readinessProbe: + httpGet: + path: / + port: 9200 + initialDelaySeconds: 15 + periodSeconds: 30 + livenessProbe: + httpGet: + path: / + port: 9200 + initialDelaySeconds: 15 + periodSeconds: 30 + volumeMounts: + - name: elasticsearch-data + mountPath: /usr/share/elasticsearch/data/ + volumes: + - name: elasticsearch-data + persistentVolumeClaim: + claimName: elasticsearch-pvc diff --git a/deploy/k8s/gateway.yaml b/deploy/k8s/gateway.yaml new file mode 100644 index 0000000..a8de073 --- /dev/null +++ b/deploy/k8s/gateway.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: nginx + namespace: djangoblog +spec: + ingressClassName: nginx + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx + port: + number: 80 \ No newline at end of file diff --git a/deploy/k8s/pv.yaml b/deploy/k8s/pv.yaml new file mode 100644 index 0000000..874b72f --- /dev/null +++ b/deploy/k8s/pv.yaml @@ -0,0 +1,94 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: local-pv-db +spec: + capacity: + storage: 10Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: local-storage + local: + path: /mnt/local-storage-db + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - master +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: local-pv-djangoblog +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: local-storage + local: + path: /mnt/local-storage-djangoblog + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - master + + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: local-pv-resource +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: local-storage + local: + path: /mnt/resource/ + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - master + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: local-pv-elasticsearch +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: local-storage + local: + path: /mnt/local-storage-elasticsearch + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - master \ No newline at end of file diff --git a/deploy/k8s/pvc.yaml b/deploy/k8s/pvc.yaml new file mode 100644 index 0000000..ef238c5 --- /dev/null +++ b/deploy/k8s/pvc.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: db-pvc + namespace: djangoblog +spec: + storageClassName: local-storage + volumeName: local-pv-db + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: djangoblog-pvc + namespace: djangoblog +spec: + volumeName: local-pv-djangoblog + storageClassName: local-storage + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: resource-pvc + namespace: djangoblog +spec: + volumeName: local-pv-resource + storageClassName: local-storage + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: elasticsearch-pvc + namespace: djangoblog +spec: + volumeName: local-pv-elasticsearch + storageClassName: local-storage + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + \ No newline at end of file diff --git a/deploy/k8s/service.yaml b/deploy/k8s/service.yaml new file mode 100644 index 0000000..4ef2931 --- /dev/null +++ b/deploy/k8s/service.yaml @@ -0,0 +1,80 @@ +apiVersion: v1 +kind: Service +metadata: + name: djangoblog + namespace: djangoblog + labels: + app: djangoblog +spec: + selector: + app: djangoblog + ports: + - protocol: TCP + port: 8000 + targetPort: 8000 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx + namespace: djangoblog + labels: + app: nginx +spec: + selector: + app: nginx + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: djangoblog + labels: + app: redis +spec: + selector: + app: redis + ports: + - protocol: TCP + port: 6379 + targetPort: 6379 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: db + namespace: djangoblog + labels: + app: db +spec: + selector: + app: db + ports: + - protocol: TCP + port: 3306 + targetPort: 3306 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: elasticsearch + namespace: djangoblog + labels: + app: elasticsearch +spec: + selector: + app: elasticsearch + ports: + - protocol: TCP + port: 9200 + targetPort: 9200 + type: ClusterIP + diff --git a/deploy/k8s/storageclass.yaml b/deploy/k8s/storageclass.yaml new file mode 100644 index 0000000..5d5a14c --- /dev/null +++ b/deploy/k8s/storageclass.yaml @@ -0,0 +1,10 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-storage + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: Immediate + + diff --git a/deploy/nginx.conf b/deploy/nginx.conf new file mode 100644 index 0000000..32161d8 --- /dev/null +++ b/deploy/nginx.conf @@ -0,0 +1,50 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + server { + root /code/djangoblog/collectedstatic/; + listen 80; + keepalive_timeout 70; + location /static/ { + expires max; + alias /code/djangoblog/collectedstatic/; + } + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + proxy_redirect off; + if (!-f $request_filename) { + proxy_pass http://djangoblog:8000; + break; + } + } + } +} diff --git a/djangoblog/__init__.py b/djangoblog/__init__.py new file mode 100644 index 0000000..1e205f4 --- /dev/null +++ b/djangoblog/__init__.py @@ -0,0 +1 @@ +default_app_config = 'djangoblog.apps.DjangoblogAppConfig' diff --git a/djangoblog/admin_site.py b/djangoblog/admin_site.py new file mode 100644 index 0000000..f120405 --- /dev/null +++ b/djangoblog/admin_site.py @@ -0,0 +1,64 @@ +from django.contrib.admin import AdminSite +from django.contrib.admin.models import LogEntry +from django.contrib.sites.admin import SiteAdmin +from django.contrib.sites.models import Site + +from accounts.admin import * +from blog.admin import * +from blog.models import * +from comments.admin import * +from comments.models import * +from djangoblog.logentryadmin import LogEntryAdmin +from oauth.admin import * +from oauth.models import * +from owntracks.admin import * +from owntracks.models import * +from servermanager.admin import * +from servermanager.models import * + + +class DjangoBlogAdminSite(AdminSite): + site_header = 'djangoblog administration' + site_title = 'djangoblog site admin' + + def __init__(self, name='admin'): + super().__init__(name) + + def has_permission(self, request): + return request.user.is_superuser + + # def get_urls(self): + # urls = super().get_urls() + # from django.urls import path + # from blog.views import refresh_memcache + # + # my_urls = [ + # path('refresh/', self.admin_view(refresh_memcache), name="refresh"), + # ] + # return urls + my_urls + + +admin_site = DjangoBlogAdminSite(name='admin') + +admin_site.register(Article, ArticlelAdmin) +admin_site.register(Category, CategoryAdmin) +admin_site.register(Tag, TagAdmin) +admin_site.register(Links, LinksAdmin) +admin_site.register(SideBar, SideBarAdmin) +admin_site.register(BlogSettings, BlogSettingsAdmin) + +admin_site.register(commands, CommandsAdmin) +admin_site.register(EmailSendLog, EmailSendLogAdmin) + +admin_site.register(BlogUser, BlogUserAdmin) + +admin_site.register(Comment, CommentAdmin) + +admin_site.register(OAuthUser, OAuthUserAdmin) +admin_site.register(OAuthConfig, OAuthConfigAdmin) + +admin_site.register(OwnTrackLog, OwnTrackLogsAdmin) + +admin_site.register(Site, SiteAdmin) + +admin_site.register(LogEntry, LogEntryAdmin) diff --git a/djangoblog/apps.py b/djangoblog/apps.py new file mode 100644 index 0000000..d29e318 --- /dev/null +++ b/djangoblog/apps.py @@ -0,0 +1,11 @@ +from django.apps import AppConfig + +class DjangoblogAppConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'djangoblog' + + def ready(self): + super().ready() + # Import and load plugins here + from .plugin_manage.loader import load_plugins + load_plugins() \ No newline at end of file diff --git a/djangoblog/blog_signals.py b/djangoblog/blog_signals.py new file mode 100644 index 0000000..393f441 --- /dev/null +++ b/djangoblog/blog_signals.py @@ -0,0 +1,122 @@ +import _thread +import logging + +import django.dispatch +from django.conf import settings +from django.contrib.admin.models import LogEntry +from django.contrib.auth.signals import user_logged_in, user_logged_out +from django.core.mail import EmailMultiAlternatives +from django.db.models.signals import post_save +from django.dispatch import receiver + +from comments.models import Comment +from comments.utils import send_comment_email +from djangoblog.spider_notify import SpiderNotify +from djangoblog.utils import cache, expire_view_cache, delete_sidebar_cache, delete_view_cache +from djangoblog.utils import get_current_site +from oauth.models import OAuthUser + +logger = logging.getLogger(__name__) + +oauth_user_login_signal = django.dispatch.Signal(['id']) +send_email_signal = django.dispatch.Signal( + ['emailto', 'title', 'content']) + + +@receiver(send_email_signal) +def send_email_signal_handler(sender, **kwargs): + emailto = kwargs['emailto'] + title = kwargs['title'] + content = kwargs['content'] + + msg = EmailMultiAlternatives( + title, + content, + from_email=settings.DEFAULT_FROM_EMAIL, + to=emailto) + msg.content_subtype = "html" + + from servermanager.models import EmailSendLog + log = EmailSendLog() + log.title = title + log.content = content + log.emailto = ','.join(emailto) + + try: + result = msg.send() + log.send_result = result > 0 + except Exception as e: + logger.error(f"失败邮箱号: {emailto}, {e}") + log.send_result = False + log.save() + + +@receiver(oauth_user_login_signal) +def oauth_user_login_signal_handler(sender, **kwargs): + id = kwargs['id'] + oauthuser = OAuthUser.objects.get(id=id) + site = get_current_site().domain + if oauthuser.picture and not oauthuser.picture.find(site) >= 0: + from djangoblog.utils import save_user_avatar + oauthuser.picture = save_user_avatar(oauthuser.picture) + oauthuser.save() + + delete_sidebar_cache() + + +@receiver(post_save) +def model_post_save_callback( + sender, + instance, + created, + raw, + using, + update_fields, + **kwargs): + clearcache = False + if isinstance(instance, LogEntry): + return + if 'get_full_url' in dir(instance): + is_update_views = update_fields == {'views'} + if not settings.TESTING and not is_update_views: + try: + notify_url = instance.get_full_url() + SpiderNotify.baidu_notify([notify_url]) + except Exception as ex: + logger.error("notify sipder", ex) + if not is_update_views: + clearcache = True + + if isinstance(instance, Comment): + if instance.is_enable: + path = instance.article.get_absolute_url() + site = get_current_site().domain + if site.find(':') > 0: + site = site[0:site.find(':')] + + 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) + cache.delete(comment_cache_key) + delete_sidebar_cache() + delete_view_cache('article_comments', [str(instance.article.pk)]) + + _thread.start_new_thread(send_comment_email, (instance,)) + + if clearcache: + cache.clear() + + +@receiver(user_logged_in) +@receiver(user_logged_out) +def user_auth_callback(sender, request, user, **kwargs): + if user and user.username: + logger.info(user) + delete_sidebar_cache() + # cache.clear() diff --git a/djangoblog/elasticsearch_backend.py b/djangoblog/elasticsearch_backend.py new file mode 100644 index 0000000..4afe498 --- /dev/null +++ b/djangoblog/elasticsearch_backend.py @@ -0,0 +1,183 @@ +from django.utils.encoding import force_str +from elasticsearch_dsl import Q +from haystack.backends import BaseEngine, BaseSearchBackend, BaseSearchQuery, log_query +from haystack.forms import ModelSearchForm +from haystack.models import SearchResult +from haystack.utils import log as logging + +from blog.documents import ArticleDocument, ArticleDocumentManager +from blog.models import Article + +logger = logging.getLogger(__name__) + + +class ElasticSearchBackend(BaseSearchBackend): + def __init__(self, connection_alias, **connection_options): + super( + ElasticSearchBackend, + self).__init__( + connection_alias, + **connection_options) + self.manager = ArticleDocumentManager() + self.include_spelling = True + + def _get_models(self, iterable): + models = iterable if iterable and iterable[0] else Article.objects.all() + docs = self.manager.convert_to_doc(models) + return docs + + def _create(self, models): + self.manager.create_index() + docs = self._get_models(models) + self.manager.rebuild(docs) + + def _delete(self, models): + for m in models: + m.delete() + return True + + def _rebuild(self, models): + models = models if models else Article.objects.all() + docs = self.manager.convert_to_doc(models) + self.manager.update_docs(docs) + + def update(self, index, iterable, commit=True): + + models = self._get_models(iterable) + self.manager.update_docs(models) + + def remove(self, obj_or_string): + models = self._get_models([obj_or_string]) + self._delete(models) + + def clear(self, models=None, commit=True): + self.remove(None) + + @staticmethod + def get_suggestion(query: str) -> str: + """获取推荐词, 如果没有找到添加原搜索词""" + + search = ArticleDocument.search() \ + .query("match", body=query) \ + .suggest('suggest_search', query, term={'field': 'body'}) \ + .execute() + + keywords = [] + for suggest in search.suggest.suggest_search: + if suggest["options"]: + keywords.append(suggest["options"][0]["text"]) + else: + keywords.append(suggest["text"]) + + return ' '.join(keywords) + + @log_query + def search(self, query_string, **kwargs): + logger.info('search query_string:' + query_string) + + start_offset = kwargs.get('start_offset') + end_offset = kwargs.get('end_offset') + + # 推荐词搜索 + if getattr(self, "is_suggest", None): + suggestion = self.get_suggestion(query_string) + else: + suggestion = query_string + + q = Q('bool', + should=[Q('match', body=suggestion), Q('match', title=suggestion)], + 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] + + results = search.execute() + hits = results['hits'].total + raw_results = [] + for raw_result in results['hits']['hits']: + app_label = 'blog' + model_name = 'Article' + additional_fields = {} + + result_class = SearchResult + + result = result_class( + app_label, + model_name, + raw_result['_id'], + raw_result['_score'], + **additional_fields) + raw_results.append(result) + facets = {} + spelling_suggestion = None if query_string == suggestion else suggestion + + return { + 'results': raw_results, + 'hits': hits, + 'facets': facets, + 'spelling_suggestion': spelling_suggestion, + } + + +class ElasticSearchQuery(BaseSearchQuery): + def _convert_datetime(self, date): + if hasattr(date, 'hour'): + return force_str(date.strftime('%Y%m%d%H%M%S')) + else: + return force_str(date.strftime('%Y%m%d000000')) + + def clean(self, query_fragment): + """ + Provides a mechanism for sanitizing user input before presenting the + value to the backend. + + Whoosh 1.X differs here in that you can no longer use a backslash + to escape reserved characters. Instead, the whole word should be + quoted. + """ + words = query_fragment.split() + cleaned_words = [] + + for word in words: + if word in self.backend.RESERVED_WORDS: + word = word.replace(word, word.lower()) + + for char in self.backend.RESERVED_CHARACTERS: + if char in word: + word = "'%s'" % word + break + + cleaned_words.append(word) + + return ' '.join(cleaned_words) + + def build_query_fragment(self, field, filter_type, value): + return value.query_string + + def get_count(self): + results = self.get_results() + return len(results) if results else 0 + + def get_spelling_suggestion(self, preferred_query=None): + return self._spelling_suggestion + + def build_params(self, spelling_query=None): + kwargs = super(ElasticSearchQuery, self).build_params(spelling_query=spelling_query) + return kwargs + + +class ElasticSearchModelSearchForm(ModelSearchForm): + + def search(self): + # 是否建议搜索 + self.searchqueryset.query.backend.is_suggest = self.data.get("is_suggest") != "no" + sqs = super().search() + return sqs + + +class ElasticSearchEngine(BaseEngine): + backend = ElasticSearchBackend + query = ElasticSearchQuery diff --git a/djangoblog/feeds.py b/djangoblog/feeds.py new file mode 100644 index 0000000..8c4e851 --- /dev/null +++ b/djangoblog/feeds.py @@ -0,0 +1,40 @@ +from django.contrib.auth import get_user_model +from django.contrib.syndication.views import Feed +from django.utils import timezone +from django.utils.feedgenerator import Rss201rev2Feed + +from blog.models import Article +from djangoblog.utils import CommonMarkdown + + +class DjangoBlogFeed(Feed): + feed_type = Rss201rev2Feed + + description = '大巧无工,重剑无锋.' + title = "且听风吟 大巧无工,重剑无锋. " + link = "/feed/" + + def author_name(self): + return get_user_model().objects.first().nickname + + def author_link(self): + return get_user_model().objects.first().get_absolute_url() + + def items(self): + return Article.objects.filter(type='a', status='p').order_by('-pub_time')[:5] + + def item_title(self, item): + return item.title + + def item_description(self, item): + return CommonMarkdown.get_markdown(item.body) + + def feed_copyright(self): + now = timezone.now() + return "Copyright© {year} 且听风吟".format(year=now.year) + + def item_link(self, item): + return item.get_absolute_url() + + def item_guid(self, item): + return diff --git a/djangoblog/logentryadmin.py b/djangoblog/logentryadmin.py new file mode 100644 index 0000000..2f6a535 --- /dev/null +++ b/djangoblog/logentryadmin.py @@ -0,0 +1,91 @@ +from django.contrib import admin +from django.contrib.admin.models import DELETION +from django.contrib.contenttypes.models import ContentType +from django.urls import reverse, NoReverseMatch +from django.utils.encoding import force_str +from django.utils.html import escape +from django.utils.safestring import mark_safe +from django.utils.translation import gettext_lazy as _ + + +class LogEntryAdmin(admin.ModelAdmin): + list_filter = [ + 'content_type' + ] + + search_fields = [ + 'object_repr', + 'change_message' + ] + + list_display_links = [ + 'action_time', + 'get_change_message', + ] + list_display = [ + 'action_time', + 'user_link', + 'content_type', + 'object_link', + 'get_change_message', + ] + + def has_add_permission(self, request): + return False + + 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' + + def has_delete_permission(self, request, obj=None): + return False + + def object_link(self, obj): + object_link = escape(obj.object_repr) + content_type = obj.content_type + + if obj.action_flag != DELETION and content_type is not None: + # try returning an actual link instead of object repr string + try: + url = reverse( + 'admin:{}_{}_change'.format(content_type.app_label, + content_type.model), + args=[obj.object_id] + ) + object_link = '{}'.format(url, object_link) + except NoReverseMatch: + pass + return mark_safe(object_link) + + object_link.admin_order_field = 'object_repr' + object_link.short_description = _('object') + + def user_link(self, obj): + content_type = ContentType.objects.get_for_model(type(obj.user)) + user_link = escape(force_str(obj.user)) + try: + # try returning an actual link instead of object repr string + url = reverse( + 'admin:{}_{}_change'.format(content_type.app_label, + content_type.model), + args=[obj.user.pk] + ) + user_link = '{}'.format(url, user_link) + except NoReverseMatch: + pass + return mark_safe(user_link) + + user_link.admin_order_field = 'user' + user_link.short_description = _('user') + + def get_queryset(self, request): + queryset = super(LogEntryAdmin, self).get_queryset(request) + return queryset.prefetch_related('content_type') + + def get_actions(self, request): + actions = super(LogEntryAdmin, self).get_actions(request) + if 'delete_selected' in actions: + del actions['delete_selected'] + return actions diff --git a/djangoblog/plugin_manage/base_plugin.py b/djangoblog/plugin_manage/base_plugin.py new file mode 100644 index 0000000..2b4be5c --- /dev/null +++ b/djangoblog/plugin_manage/base_plugin.py @@ -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 + } diff --git a/djangoblog/plugin_manage/hook_constants.py b/djangoblog/plugin_manage/hook_constants.py new file mode 100644 index 0000000..6685b7c --- /dev/null +++ b/djangoblog/plugin_manage/hook_constants.py @@ -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" + diff --git a/djangoblog/plugin_manage/hooks.py b/djangoblog/plugin_manage/hooks.py new file mode 100644 index 0000000..d712540 --- /dev/null +++ b/djangoblog/plugin_manage/hooks.py @@ -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 diff --git a/djangoblog/plugin_manage/loader.py b/djangoblog/plugin_manage/loader.py new file mode 100644 index 0000000..12e824b --- /dev/null +++ b/djangoblog/plugin_manage/loader.py @@ -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) \ No newline at end of file diff --git a/djangoblog/settings.py b/djangoblog/settings.py new file mode 100644 index 0000000..ac553fd --- /dev/null +++ b/djangoblog/settings.py @@ -0,0 +1,343 @@ +""" +Django settings for djangoblog project. + +Generated by 'django-admin startproject' using Django 1.10.2. + +For more information on this file, see +https://docs.djangoproject.com/en/1.10/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.10/ref/settings/ +""" +import os +import sys +from pathlib import Path + +from django.utils.translation import gettext_lazy as _ + + +def env_to_bool(env, default): + str_val = os.environ.get(env) + return default if str_val is None else str_val == 'True' + + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# Quick-start development settings - unsuitable for production +# 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' +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = env_to_bool('DJANGO_DEBUG', True) +# DEBUG = False +TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' + +# ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*', '127.0.0.1', 'example.com'] +# django 4.0新增配置 +CSRF_TRUSTED_ORIGINS = ['http://example.com'] +# Application definition + + +INSTALLED_APPS = [ + # 'django.contrib.admin', + 'django.contrib.admin.apps.SimpleAdminConfig', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.sites', + 'django.contrib.sitemaps', + 'mdeditor', + 'haystack', + 'blog', + 'accounts', + 'comments', + 'oauth', + 'servermanager', + 'owntracks', + 'compressor', + 'djangoblog' +] + +MIDDLEWARE = [ + + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.gzip.GZipMiddleware', + # 'django.middleware.cache.UpdateCacheMiddleware', + 'django.middleware.common.CommonMiddleware', + # 'django.middleware.cache.FetchFromCacheMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.http.ConditionalGetMiddleware', + 'blog.middleware.OnlineMiddleware' +] + +ROOT_URLCONF = 'djangoblog.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'blog.context_processors.seo_processor' + ], + }, + }, +] + +WSGI_APPLICATION = 'djangoblog.wsgi.application' + +# Database +# https://docs.djangoproject.com/en/1.10/ref/settings/#databases + + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog', + 'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root', + 'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or '2315304109', + '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'}, + }} + +# Password validation +# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +LANGUAGES = ( + ('en', _('English')), + ('zh-hans', _('Simplified Chinese')), + ('zh-hant', _('Traditional Chinese')), +) +LOCALE_PATHS = ( + os.path.join(BASE_DIR, 'locale'), +) + +LANGUAGE_CODE = 'zh-hans' + +TIME_ZONE = 'Asia/Shanghai' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = False + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.10/howto/static-files/ + + +HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'djangoblog.whoosh_cn_backend.WhooshEngine', + 'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'), + }, +} +# Automatically update searching index +HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' +# Allow user login with username and password +AUTHENTICATION_BACKENDS = [ + 'accounts.user_login_backend.EmailOrUsernameModelBackend'] + +STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic') + +STATIC_URL = '/static/' +STATICFILES = os.path.join(BASE_DIR, 'static') + +AUTH_USER_MODEL = 'accounts.BlogUser' +LOGIN_URL = '/login/' + +TIME_FORMAT = '%Y-%m-%d %H:%M:%S' +DATE_TIME_FORMAT = '%Y-%m-%d' + +# bootstrap color styles +BOOTSTRAP_COLOR_TYPES = [ + 'default', 'primary', 'success', 'info', 'warning', 'danger' +] + +# paginate +PAGINATE_BY = 10 +# http cache timeout +CACHE_CONTROL_MAX_AGE = 2592000 +# cache setting +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'TIMEOUT': 10800, + 'LOCATION': 'unique-snowflake', + } +} +# 使用redis作为缓存 +if os.environ.get("DJANGO_REDIS_URL"): + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.redis.RedisCache', + 'LOCATION': f'redis://{os.environ.get("DJANGO_REDIS_URL")}', + } + } + +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' + +# Email: +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_USE_TLS = env_to_bool('DJANGO_EMAIL_TLS', False) +EMAIL_USE_SSL = env_to_bool('DJANGO_EMAIL_SSL', True) +EMAIL_HOST = os.environ.get('DJANGO_EMAIL_HOST') or 'smtp.mxhichina.com' +EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT') or 465) +EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER') +EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD') +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +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' + +LOG_PATH = os.path.join(BASE_DIR, 'logs') +if not os.path.exists(LOG_PATH): + os.makedirs(LOG_PATH, exist_ok=True) + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'root': { + 'level': 'INFO', + 'handlers': ['console', 'log_file'], + }, + 'formatters': { + 'verbose': { + 'format': '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d %(module)s] %(message)s', + } + }, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse', + }, + 'require_debug_true': { + '()': 'django.utils.log.RequireDebugTrue', + }, + }, + 'handlers': { + 'log_file': { + 'level': 'INFO', + 'class': 'logging.handlers.TimedRotatingFileHandler', + 'filename': os.path.join(LOG_PATH, 'djangoblog.log'), + 'when': 'D', + 'formatter': 'verbose', + 'interval': 1, + 'delay': True, + 'backupCount': 5, + 'encoding': 'utf-8' + }, + 'console': { + 'level': 'DEBUG', + 'filters': ['require_debug_true'], + 'class': 'logging.StreamHandler', + 'formatter': 'verbose' + }, + 'null': { + 'class': 'logging.NullHandler', + }, + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'djangoblog': { + 'handlers': ['log_file', 'console'], + 'level': 'INFO', + 'propagate': True, + }, + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': False, + } + } +} + +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + # other + 'compressor.finders.CompressorFinder', +) +COMPRESS_ENABLED = True +# COMPRESS_OFFLINE = True + + +COMPRESS_CSS_FILTERS = [ + # creates absolute urls from relative ones + 'compressor.filters.css_default.CssAbsoluteFilter', + # css minimizer + 'compressor.filters.cssmin.CSSMinFilter' +] +COMPRESS_JS_FILTERS = [ + 'compressor.filters.jsmin.JSMinFilter' +] + +MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads') +MEDIA_URL = '/media/' +X_FRAME_OPTIONS = 'SAMEORIGIN' + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +if os.environ.get('DJANGO_ELASTICSEARCH_HOST'): + ELASTICSEARCH_DSL = { + 'default': { + 'hosts': os.environ.get('DJANGO_ELASTICSEARCH_HOST') + }, + } + HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'djangoblog.elasticsearch_backend.ElasticSearchEngine', + }, + } + +# Plugin System +PLUGINS_DIR = BASE_DIR / 'plugins' +ACTIVE_PLUGINS = [ + 'article_copyright', + 'reading_time', + 'external_links', + 'view_count', + 'seo_optimizer' +] \ No newline at end of file diff --git a/djangoblog/sitemap.py b/djangoblog/sitemap.py new file mode 100644 index 0000000..8b7d446 --- /dev/null +++ b/djangoblog/sitemap.py @@ -0,0 +1,59 @@ +from django.contrib.sitemaps import Sitemap +from django.urls import reverse + +from blog.models import Article, Category, Tag + + +class StaticViewSitemap(Sitemap): + priority = 0.5 + changefreq = 'daily' + + def items(self): + return ['blog:index', ] + + def location(self, item): + return reverse(item) + + +class ArticleSiteMap(Sitemap): + changefreq = "monthly" + priority = "0.6" + + def items(self): + return Article.objects.filter(status='p') + + def lastmod(self, obj): + return obj.last_modify_time + + +class CategorySiteMap(Sitemap): + changefreq = "Weekly" + priority = "0.6" + + def items(self): + return Category.objects.all() + + def lastmod(self, obj): + return obj.last_modify_time + + +class TagSiteMap(Sitemap): + changefreq = "Weekly" + priority = "0.3" + + def items(self): + return Tag.objects.all() + + def lastmod(self, obj): + return obj.last_modify_time + + +class UserSiteMap(Sitemap): + changefreq = "Weekly" + priority = "0.3" + + def items(self): + return list(set(map(lambda x: x.author, Article.objects.all()))) + + def lastmod(self, obj): + return obj.date_joined diff --git a/djangoblog/spider_notify.py b/djangoblog/spider_notify.py new file mode 100644 index 0000000..7b909e9 --- /dev/null +++ b/djangoblog/spider_notify.py @@ -0,0 +1,21 @@ +import logging + +import requests +from django.conf import settings + +logger = logging.getLogger(__name__) + + +class SpiderNotify(): + @staticmethod + def baidu_notify(urls): + try: + data = '\n'.join(urls) + result = requests.post(settings.BAIDU_NOTIFY_URL, data=data) + logger.info(result.text) + except Exception as e: + logger.error(e) + + @staticmethod + def notify(url): + SpiderNotify.baidu_notify(url) diff --git a/djangoblog/tests.py b/djangoblog/tests.py new file mode 100644 index 0000000..01237d9 --- /dev/null +++ b/djangoblog/tests.py @@ -0,0 +1,32 @@ +from django.test import TestCase + +from djangoblog.utils import * + + +class DjangoBlogTest(TestCase): + def setUp(self): + pass + + def test_utils(self): + md5 = get_sha256('test') + self.assertIsNotNone(md5) + c = CommonMarkdown.get_markdown(''' + # Title1 + + ```python + import os + ``` + + [url](https://www.lylinux.net/) + + [ddd](http://www.baidu.com) + + + ''') + self.assertIsNotNone(c) + d = { + 'd': 'key1', + 'd2': 'key2' + } + data = parse_dict_to_url(d) + self.assertIsNotNone(data) diff --git a/djangoblog/urls.py b/djangoblog/urls.py new file mode 100644 index 0000000..4aae58a --- /dev/null +++ b/djangoblog/urls.py @@ -0,0 +1,64 @@ +"""djangoblog URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.10/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.conf.urls import url, include + 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf import settings +from django.conf.urls.i18n import i18n_patterns +from django.conf.urls.static import static +from django.contrib.sitemaps.views import sitemap +from django.urls import path, include +from django.urls import re_path +from haystack.views import search_view_factory + +from blog.views import EsSearchView +from djangoblog.admin_site import admin_site +from djangoblog.elasticsearch_backend import ElasticSearchModelSearchForm +from djangoblog.feeds import DjangoBlogFeed +from djangoblog.sitemap import ArticleSiteMap, CategorySiteMap, StaticViewSitemap, TagSiteMap, UserSiteMap + +sitemaps = { + + 'blog': ArticleSiteMap, + 'Category': CategorySiteMap, + 'Tag': TagSiteMap, + 'User': UserSiteMap, + 'static': StaticViewSitemap +} + +handler404 = 'blog.views.page_not_found_view' +handler500 = 'blog.views.server_error_view' +handle403 = 'blog.views.permission_denied_view' + +urlpatterns = [ + path('i18n/', include('django.conf.urls.i18n')), +] +urlpatterns += i18n_patterns( + re_path(r'^admin/', admin_site.urls), + re_path(r'', include('blog.urls', namespace='blog')), + re_path(r'mdeditor/', include('mdeditor.urls')), + re_path(r'', include('comments.urls', namespace='comment')), + re_path(r'', include('accounts.urls', namespace='account')), + re_path(r'', include('oauth.urls', namespace='oauth')), + re_path(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}, + name='django.contrib.sitemaps.views.sitemap'), + re_path(r'^feed/$', DjangoBlogFeed()), + re_path(r'^rss/$', DjangoBlogFeed()), + re_path('^search', search_view_factory(view_class=EsSearchView, form_class=ElasticSearchModelSearchForm), + name='search'), + re_path(r'', include('servermanager.urls', namespace='servermanager')), + re_path(r'', include('owntracks.urls', namespace='owntracks')) + , prefix_default_language=False) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, + document_root=settings.MEDIA_ROOT) diff --git a/djangoblog/utils.py b/djangoblog/utils.py new file mode 100644 index 0000000..57f63dc --- /dev/null +++ b/djangoblog/utils.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +import logging +import os +import random +import string +import uuid +from hashlib import sha256 + +import bleach +import markdown +import requests +from django.conf import settings +from django.contrib.sites.models import Site +from django.core.cache import cache +from django.templatetags.static import static + +logger = logging.getLogger(__name__) + + +def get_max_articleid_commentid(): + from blog.models import Article + from comments.models import Comment + return (Article.objects.latest().pk, Comment.objects.latest().pk) + + +def get_sha256(str): + m = sha256(str.encode('utf-8')) + return m.hexdigest() + + +def cache_decorator(expiration=3 * 60): + def wrapper(func): + def news(*args, **kwargs): + try: + view = args[0] + key = view.get_cache_key() + except: + key = None + if not key: + unique_str = repr((func, args, kwargs)) + + m = sha256(unique_str.encode('utf-8')) + key = m.hexdigest() + value = cache.get(key) + if value is not None: + # logger.info('cache_decorator get cache:%s key:%s' % (func.__name__, key)) + if str(value) == '__default_cache_value__': + return None + else: + return value + else: + logger.debug( + '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) + else: + cache.set(key, value, expiration) + return value + + return news + + return wrapper + + +def expire_view_cache(path, servername, serverport, key_prefix=None): + ''' + 刷新视图缓存 + :param path:url路径 + :param servername:host + :param serverport:端口 + :param key_prefix:前缀 + :return:是否成功 + ''' + from django.http import HttpRequest + from django.utils.cache import get_cache_key + + request = HttpRequest() + request.META = {'SERVER_NAME': servername, 'SERVER_PORT': serverport} + request.path = path + + key = get_cache_key(request, key_prefix=key_prefix, cache=cache) + if key: + logger.info('expire_view_cache:get key:{path}'.format(path=path)) + if cache.get(key): + cache.delete(key) + return True + return False + + +@cache_decorator() +def get_current_site(): + site = Site.objects.get_current() + return site + + +class CommonMarkdown: + @staticmethod + def _convert_markdown(value): + md = markdown.Markdown( + extensions=[ + 'extra', + 'codehilite', + 'toc', + 'tables', + ] + ) + body = md.convert(value) + toc = md.toc + return body, toc + + @staticmethod + def get_markdown_with_toc(value): + body, toc = CommonMarkdown._convert_markdown(value) + return body, toc + + @staticmethod + def get_markdown(value): + body, toc = CommonMarkdown._convert_markdown(value) + return body + + +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) + + +def generate_code() -> str: + """生成随机数验证码""" + return ''.join(random.sample(string.digits, 6)) + + +def parse_dict_to_url(dict): + from urllib.parse import quote + url = '&'.join(['{}={}'.format(quote(k, safe='/'), quote(v, safe='/')) + for k, v in dict.items()]) + return url + + +def get_blog_setting(): + value = cache.get('get_blog_setting') + if value: + return value + else: + from blog.models import BlogSettings + if not BlogSettings.objects.count(): + setting = BlogSettings() + setting.site_name = 'djangoblog' + setting.site_description = '基于Django的博客系统' + setting.site_seo_description = '基于Django的博客系统' + setting.site_keywords = 'Django,Python' + setting.article_sub_length = 300 + setting.sidebar_article_count = 10 + setting.sidebar_comment_count = 5 + setting.show_google_adsense = False + setting.open_site_comment = True + setting.analytics_code = '' + setting.beian_code = '' + setting.show_gongan_code = False + setting.comment_need_review = False + setting.save() + value = BlogSettings.objects.first() + logger.info('set cache get_blog_setting') + cache.set('get_blog_setting', value) + return value + + +def save_user_avatar(url): + ''' + 保存用户头像 + :param url:头像url + :return: 本地路径 + ''' + logger.info(url) + + try: + basedir = os.path.join(settings.STATICFILES, 'avatar') + rsp = requests.get(url, timeout=2) + if rsp.status_code == 200: + if not os.path.exists(basedir): + os.makedirs(basedir) + + image_extensions = ['.jpg', '.png', 'jpeg', '.gif'] + isimage = len([i for i in image_extensions if url.endswith(i)]) > 0 + ext = os.path.splitext(url)[1] if isimage else '.jpg' + save_filename = str(uuid.uuid4().hex) + ext + logger.info('保存用户头像:' + basedir + save_filename) + with open(os.path.join(basedir, save_filename), 'wb+') as file: + file.write(rsp.content) + return static('avatar/' + save_filename) + except Exception as e: + logger.error(e) + return static('blog/img/avatar.png') + + +def delete_sidebar_cache(): + from blog.models import LinkShowType + keys = ["sidebar" + x for x in LinkShowType.values] + for k in keys: + logger.info('delete sidebar key:' + k) + cache.delete(k) + + +def delete_view_cache(prefix, keys): + from django.core.cache.utils import make_template_fragment_key + key = make_template_fragment_key(prefix, keys) + cache.delete(key) + + +def get_resource_url(): + if settings.STATIC_URL: + return settings.STATIC_URL + else: + site = get_current_site() + return 'http://' + site.domain + '/static/' + + +ALLOWED_TAGS = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', 'h1', + 'h2', 'p'] +ALLOWED_ATTRIBUTES = {'a': ['href', 'title'], 'abbr': ['title'], 'acronym': ['title']} + + +def sanitize_html(html): + return bleach.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES) diff --git a/djangoblog/whoosh_cn_backend.py b/djangoblog/whoosh_cn_backend.py new file mode 100644 index 0000000..04e3f7f --- /dev/null +++ b/djangoblog/whoosh_cn_backend.py @@ -0,0 +1,1044 @@ +# encoding: utf-8 + +from __future__ import absolute_import, division, print_function, unicode_literals + +import json +import os +import re +import shutil +import threading +import warnings + +import six +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from datetime import datetime +from django.utils.encoding import force_str +from haystack.backends import BaseEngine, BaseSearchBackend, BaseSearchQuery, EmptyResults, log_query +from haystack.constants import DJANGO_CT, DJANGO_ID, ID +from haystack.exceptions import MissingDependency, SearchBackendError, SkipDocument +from haystack.inputs import Clean, Exact, PythonData, Raw +from haystack.models import SearchResult +from haystack.utils import get_identifier, get_model_ct +from haystack.utils import log as logging +from haystack.utils.app_loading import haystack_get_model +from jieba.analyse import ChineseAnalyzer +from whoosh import index +from whoosh.analysis import StemmingAnalyzer +from whoosh.fields import BOOLEAN, DATETIME, IDLIST, KEYWORD, NGRAM, NGRAMWORDS, NUMERIC, Schema, TEXT +from whoosh.fields import ID as WHOOSH_ID +from whoosh.filedb.filestore import FileStorage, RamStorage +from whoosh.highlight import ContextFragmenter, HtmlFormatter +from whoosh.highlight import highlight as whoosh_highlight +from whoosh.qparser import QueryParser +from whoosh.searching import ResultsPage +from whoosh.writing import AsyncWriter + +try: + import whoosh +except ImportError: + raise MissingDependency( + "The 'whoosh' backend requires the installation of 'Whoosh'. Please refer to the documentation.") + +# 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.") + +# Bubble up the correct error. + +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?)?$') +LOCALS = threading.local() +LOCALS.RAM_STORE = None + + +class WhooshHtmlFormatter(HtmlFormatter): + """ + This is a HtmlFormatter simpler than the whoosh.HtmlFormatter. + We use it to have consistent results across backends. Specifically, + Solr, Xapian and Elasticsearch are using this formatting. + """ + template = '<%(tag)s>%(t)s' + + +class WhooshSearchBackend(BaseSearchBackend): + # Word reserved by Whoosh for special use. + RESERVED_WORDS = ( + 'AND', + 'NOT', + 'OR', + 'TO', + ) + + # Characters reserved by Whoosh for special use. + # 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) + self.setup_complete = False + self.use_file_storage = True + self.post_limit = getattr( + connection_options, + 'POST_LIMIT', + 128 * 1024 * 1024) + self.path = connection_options.get('PATH') + + if connection_options.get('STORAGE', 'file') != 'file': + self.use_file_storage = False + + if self.use_file_storage and not self.path: + raise ImproperlyConfigured( + "You must specify a 'PATH' in your settings for connection '%s'." % + connection_alias) + + self.log = logging.getLogger('haystack') + + def setup(self): + """ + Defers loading until needed. + """ + from haystack import connections + new_index = False + + # Make sure the index is there. + if self.use_file_storage and not os.path.exists(self.path): + os.makedirs(self.path) + 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) + + if self.use_file_storage: + self.storage = FileStorage(self.path) + else: + global LOCALS + + if getattr(LOCALS, 'RAM_STORE', None) is None: + LOCALS.RAM_STORE = RamStorage() + + self.storage = LOCALS.RAM_STORE + + self.content_field_name, self.schema = self.build_schema( + connections[self.connection_alias].get_unified_index().all_searchfields()) + self.parser = QueryParser(self.content_field_name, schema=self.schema) + + if new_index is True: + self.index = self.storage.create_index(self.schema) + else: + try: + self.index = self.storage.open_index(schema=self.schema) + except index.EmptyIndexError: + self.index = self.storage.create_index(self.schema) + + self.setup_complete = True + + def build_schema(self, fields): + schema_fields = { + ID: WHOOSH_ID(stored=True, unique=True), + DJANGO_CT: WHOOSH_ID(stored=True), + DJANGO_ID: WHOOSH_ID(stored=True), + } + # Grab the number of keys that are hard-coded into Haystack. + # We'll use this to (possibly) fail slightly more gracefully later. + initial_key_count = len(schema_fields) + content_field_name = '' + + 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) + else: + 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) + elif field_class.field_type == 'integer': + 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) + 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) + 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) + 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) + if field_class.document is True: + content_field_name = field_class.index_fieldname + schema_fields[field_class.index_fieldname].spelling = True + + # Fail more gracefully than relying on the backend to die if no fields + # are found. + if len(schema_fields) <= initial_key_count: + raise SearchBackendError( + "No fields were found in any search_indexes. Please correct this before attempting to search.") + + return (content_field_name, Schema(**schema_fields)) + + def update(self, index, iterable, commit=True): + if not self.setup_complete: + self.setup() + + self.index = self.index.refresh() + writer = AsyncWriter(self.index) + + for obj in iterable: + try: + doc = index.full_prepare(obj) + except SkipDocument: + self.log.debug(u"Indexing for object `%s` skipped", obj) + else: + # Really make sure it's unicode, because Whoosh won't have it any + # other way. + for key in doc: + doc[key] = self._from_python(doc[key]) + + # Document boosts aren't supported in Whoosh 2.5.0+. + if 'boost' in doc: + del doc['boost'] + + try: + writer.update_document(**doc) + except Exception as e: + if not self.silently_fail: + raise + + # 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)}}) + + if len(iterable) > 0: + # For now, commit no matter what, as we run into locking issues + # otherwise. + writer.commit() + + def remove(self, obj_or_string, commit=True): + if not self.setup_complete: + self.setup() + + self.index = self.index.refresh() + whoosh_id = get_identifier(obj_or_string) + + try: + 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) + + def clear(self, models=None, commit=True): + if not self.setup_complete: + self.setup() + + self.index = self.index.refresh() + + if models is not None: + assert isinstance(models, (list, tuple)) + + try: + if models is None: + self.delete_index() + else: + models_to_delete = [] + + for model in models: + 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))) + 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) + else: + 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, + # it's much more efficient to simply delete the index files. + if self.use_file_storage and os.path.exists(self.path): + shutil.rmtree(self.path) + elif not self.use_file_storage: + self.storage.clean() + + # Recreate everything. + self.setup() + + def optimize(self): + if not self.setup_complete: + self.setup() + + self.index = self.index.refresh() + self.index.optimize() + + def calculate_page(self, start_offset=0, end_offset=None): + # Prevent against Whoosh throwing an error. Requires an end_offset + # greater than 0. + if end_offset is not None and end_offset <= 0: + end_offset = 1 + + # Determine the page. + page_num = 0 + + if end_offset is None: + end_offset = 1000000 + + if start_offset is None: + start_offset = 0 + + page_length = end_offset - start_offset + + if page_length and page_length > 0: + page_num = int(start_offset / page_length) + + # Increment because Whoosh uses 1-based page numbers. + page_num += 1 + 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): + if not self.setup_complete: + self.setup() + + # A zero length query should return no results. + if len(query_string) == 0: + return { + 'results': [], + 'hits': 0, + } + + query_string = force_str(query_string) + + # A one-character query (non-wildcard) gets nabbed by a stopwords + # filter and should yield zero results. + if len(query_string) <= 1 and query_string != u'*': + return { + 'results': [], + 'hits': 0, + } + + reverse = False + + if sort_by is not None: + # Determine if we need to reverse the results and if Whoosh can + # handle what it's being asked to sort by. Reversing is an + # all-or-nothing action, unfortunately. + sort_by_list = [] + reverse_counter = 0 + + for order_by in sort_by: + if order_by.startswith('-'): + reverse_counter += 1 + + if reverse_counter and reverse_counter != len(sort_by): + raise SearchBackendError("Whoosh requires all order_by fields" + " to use the same sort direction") + + for order_by in sort_by: + if order_by.startswith('-'): + sort_by_list.append(order_by[1:]) + + if len(sort_by_list) == 1: + reverse = True + else: + sort_by_list.append(order_by) + + if len(sort_by_list) == 1: + reverse = False + + sort_by = sort_by_list[0] + + if facets is not None: + 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) + + if query_facets is not None: + 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) + + if models and len(models): + model_choices = sorted(get_model_ct(model) for model in models) + elif limit_to_registered_models: + # Using narrow queries, limit the results to only models handled + # with the current routers. + model_choices = self.build_models_list() + else: + model_choices = [] + + if len(model_choices) > 0: + if narrow_queries is None: + narrow_queries = set() + + 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... + narrow_searcher = self.index.searcher() + + for nq in narrow_queries: + recent_narrowed_results = narrow_searcher.search( + self.parser.parse(force_str(nq)), limit=None) + + if len(recent_narrowed_results) <= 0: + return { + 'results': [], + 'hits': 0, + } + + if narrowed_results: + narrowed_results.filter(recent_narrowed_results) + else: + narrowed_results = recent_narrowed_results + + self.index = self.index.refresh() + + if self.index.doc_count(): + searcher = self.index.searcher() + parsed_query = self.parser.parse(query_string) + + # In the event of an invalid/stopworded query, recover gracefully. + if parsed_query is None: + return { + 'results': [], + 'hits': 0, + } + + page_num, page_length = self.calculate_page( + start_offset, end_offset) + + search_kwargs = { + 'pagelen': page_length, + 'sortedby': sort_by, + 'reverse': reverse, + } + + # Handle the case where the results have been narrowed. + if narrowed_results is not None: + search_kwargs['filter'] = narrowed_results + + try: + raw_page = searcher.search_page( + parsed_query, + page_num, + **search_kwargs + ) + except ValueError: + if not self.silently_fail: + raise + + return { + 'results': [], + 'hits': 0, + 'spelling_suggestion': None, + } + + # Because as of Whoosh 2.5.1, it will return the wrong page of + # results if you request something too high. :( + if raw_page.pagenum < page_num: + return { + 'results': [], + 'hits': 0, + 'spelling_suggestion': None, + } + + 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'): + narrow_searcher.close() + + return results + else: + if self.include_spelling: + if spelling_query: + spelling_suggestion = self.create_spelling_suggestion( + spelling_query) + else: + spelling_suggestion = self.create_spelling_suggestion( + query_string) + else: + spelling_suggestion = None + + return { + 'results': [], + 'hits': 0, + '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): + if not self.setup_complete: + self.setup() + + # Deferred models will have a different class ("RealClass_Deferred_fieldname") + # which won't be in our registry: + model_klass = model_instance._meta.concrete_model + + field_name = self.content_field_name + narrow_queries = set() + 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) + + if models and len(models): + model_choices = sorted(get_model_ct(model) for model in models) + elif limit_to_registered_models: + # Using narrow queries, limit the results to only models handled + # with the current routers. + model_choices = self.build_models_list() + else: + model_choices = [] + + if len(model_choices) > 0: + if narrow_queries is None: + narrow_queries = set() + + 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) + + narrow_searcher = None + + if narrow_queries is not None: + # 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_str(nq)), limit=None) + + if len(recent_narrowed_results) <= 0: + return { + 'results': [], + 'hits': 0, + } + + if narrowed_results: + narrowed_results.filter(recent_narrowed_results) + else: + narrowed_results = recent_narrowed_results + + page_num, page_length = self.calculate_page(start_offset, end_offset) + + self.index = self.index.refresh() + raw_results = EmptyResults() + + if self.index.doc_count(): + query = "%s:%s" % (ID, get_identifier(model_instance)) + searcher = self.index.searcher() + parsed_query = self.parser.parse(query) + results = searcher.search(parsed_query) + + if len(results): + 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'): + raw_results.filter(narrowed_results) + + try: + raw_page = ResultsPage(raw_results, page_num, page_length) + except ValueError: + if not self.silently_fail: + raise + + return { + 'results': [], + 'hits': 0, + 'spelling_suggestion': None, + } + + # Because as of Whoosh 2.5.1, it will return the wrong page of + # results if you request something too high. :( + if raw_page.pagenum < page_num: + return { + 'results': [], + 'hits': 0, + 'spelling_suggestion': None, + } + + results = self._process_results(raw_page, result_class=result_class) + searcher.close() + + if hasattr(narrow_searcher, 'close'): + narrow_searcher.close() + + return results + + def _process_results( + self, + raw_page, + highlight=False, + query_string='', + spelling_query=None, + result_class=None): + from haystack import connections + results = [] + + # It's important to grab the hits first before slicing. Otherwise, this + # can cause pagination failures. + hits = len(raw_page) + + if result_class is None: + result_class = SearchResult + + facets = {} + spelling_suggestion = None + unified_index = connections[self.connection_alias].get_unified_index() + indexed_models = unified_index.get_indexed_models() + + for doc_offset, raw_result in enumerate(raw_page): + score = raw_page.score(doc_offset) or 0 + app_label, model_name = raw_result[DJANGO_CT].split('.') + additional_fields = {} + model = haystack_get_model(app_label, model_name) + + if model and model in indexed_models: + for key, value in raw_result.items(): + index = unified_index.get_index(model) + string_key = str(key) + + 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( + ',') + else: + additional_fields[string_key] = index.fields[string_key].convert( + value) + else: + additional_fields[string_key] = self._to_python(value) + + del (additional_fields[DJANGO_CT]) + del (additional_fields[DJANGO_ID]) + + if highlight: + sa = StemmingAnalyzer() + formatter = WhooshHtmlFormatter('em') + terms = [token.text for token in sa(query_string)] + + whoosh_result = whoosh_highlight( + additional_fields.get(self.content_field_name), + terms, + sa, + ContextFragmenter(), + formatter + ) + additional_fields['highlighted'] = { + self.content_field_name: [whoosh_result], + } + + 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) + else: + spelling_suggestion = self.create_spelling_suggestion( + query_string) + + return { + 'results': results, + 'hits': hits, + 'facets': facets, + 'spelling_suggestion': spelling_suggestion, + } + + def create_spelling_suggestion(self, query_string): + spelling_suggestion = None + reader = self.index.reader() + corrector = reader.corrector(self.content_field_name) + cleaned_query = force_str(query_string) + + if not query_string: + return spelling_suggestion + + # Clean the string. + for rev_word in self.RESERVED_WORDS: + cleaned_query = cleaned_query.replace(rev_word, '') + + for rev_char in self.RESERVED_CHARACTERS: + cleaned_query = cleaned_query.replace(rev_char, '') + + # Break it down. + query_words = cleaned_query.split() + suggested_words = [] + + for word in query_words: + suggestions = corrector.suggest(word, limit=1) + + if len(suggestions) > 0: + suggested_words.append(suggestions[0]) + + spelling_suggestion = ' '.join(suggested_words) + return spelling_suggestion + + def _from_python(self, value): + """ + Converts Python values to a string for Whoosh. + + Code courtesy of pysolr. + """ + if hasattr(value, 'strftime'): + if not hasattr(value, 'hour'): + value = datetime(value.year, value.month, value.day, 0, 0, 0) + elif isinstance(value, bool): + if value: + value = 'true' + else: + value = 'false' + elif isinstance(value, (list, tuple)): + value = u','.join([force_str(v) for v in value]) + elif isinstance(value, (six.integer_types, float)): + # Leave it alone. + pass + else: + value = force_str(value) + return value + + def _to_python(self, value): + """ + Converts values from Whoosh to native Python values. + + A port of the same method in pysolr, as they deal with data the same way. + """ + if value == 'true': + return True + elif value == 'false': + return False + + if value and isinstance(value, six.string_types): + possible_datetime = DATETIME_REGEX.search(value) + + if possible_datetime: + date_values = possible_datetime.groupdict() + + 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']) + + 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)): + return converted_value + except BaseException: + # If it fails (SyntaxError or its ilk) or we don't trust it, + # continue on. + pass + + return value + + +class WhooshSearchQuery(BaseSearchQuery): + def _convert_datetime(self, date): + if hasattr(date, 'hour'): + return force_str(date.strftime('%Y%m%d%H%M%S')) + else: + return force_str(date.strftime('%Y%m%d000000')) + + def clean(self, query_fragment): + """ + Provides a mechanism for sanitizing user input before presenting the + value to the backend. + + Whoosh 1.X differs here in that you can no longer use a backslash + to escape reserved characters. Instead, the whole word should be + quoted. + """ + words = query_fragment.split() + cleaned_words = [] + + for word in words: + if word in self.backend.RESERVED_WORDS: + word = word.replace(word, word.lower()) + + for char in self.backend.RESERVED_CHARACTERS: + if char in word: + word = "'%s'" % word + break + + cleaned_words.append(word) + + return ' '.join(cleaned_words) + + def build_query_fragment(self, field, filter_type, value): + from haystack import connections + query_frag = '' + is_datetime = False + + if not hasattr(value, 'input_type_name'): + # Handle when we've got a ``ValuesListQuerySet``... + if hasattr(value, 'values_list'): + value = list(value) + + if hasattr(value, 'strftime'): + is_datetime = True + + if isinstance(value, six.string_types) and value != ' ': + # It's not an ``InputType``. Assume ``Clean``. + value = Clean(value) + else: + value = PythonData(value) + + # Prepare the query using the InputType. + prepared_value = value.prepare(self) + + if not isinstance(prepared_value, (set, list, tuple)): + # Then convert whatever we get back to what pysolr wants if needed. + prepared_value = self.backend._from_python(prepared_value) + + # 'content' is a special reserved word, much like 'pk' in + # Django's ORM layer. It indicates 'no special field'. + if field == 'content': + index_fieldname = '' + else: + index_fieldname = u'%s:' % connections[self._using].get_unified_index( + ).get_index_fieldname(field) + + filter_types = { + 'content': '%s', + 'contains': '*%s*', + 'endswith': "*%s", + 'startswith': "%s*", + 'exact': '%s', + 'gt': "{%s to}", + 'gte': "[%s to]", + 'lt': "{to %s}", + 'lte': "[to %s]", + 'fuzzy': u'%s~', + } + + if value.post_process is False: + query_frag = prepared_value + else: + 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. + 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) + + possible_values = [prepared_value] + + for possible_value in possible_values: + terms.append( + filter_types[filter_type] % + self.backend._from_python(possible_value)) + + if len(terms) == 1: + query_frag = terms[0] + else: + query_frag = u"(%s)" % " AND ".join(terms) + elif filter_type == 'in': + in_options = [] + + for possible_value in prepared_value: + is_datetime = False + + if hasattr(possible_value, 'strftime'): + is_datetime = True + + pv = self.backend._from_python(possible_value) + + if is_datetime is True: + pv = self._convert_datetime(pv) + + if isinstance(pv, six.string_types) and not is_datetime: + in_options.append('"%s"' % pv) + else: + in_options.append('%s' % pv) + + query_frag = "(%s)" % " OR ".join(in_options) + elif filter_type == 'range': + start = self.backend._from_python(prepared_value[0]) + end = self.backend._from_python(prepared_value[1]) + + if hasattr(prepared_value[0], 'strftime'): + start = self._convert_datetime(start) + + if hasattr(prepared_value[1], 'strftime'): + end = self._convert_datetime(end) + + query_frag = u"[%s to %s]" % (start, end) + elif filter_type == 'exact': + if value.input_type_name == 'exact': + query_frag = prepared_value + else: + prepared_value = Exact(prepared_value).prepare(self) + query_frag = filter_types[filter_type] % prepared_value + else: + if is_datetime is True: + prepared_value = self._convert_datetime(prepared_value) + + query_frag = filter_types[filter_type] % prepared_value + + if len(query_frag) and not isinstance(value, Raw): + if not query_frag.startswith('(') and not query_frag.endswith(')'): + query_frag = "(%s)" % query_frag + + return u"%s%s" % (index_fieldname, query_frag) + + # if not filter_type in ('in', 'range'): + # # 'in' is a bit of a special case, as we don't want to + # # convert a valid list/tuple to string. Defer handling it + # # until later... + # value = self.backend._from_python(value) + + +class WhooshEngine(BaseEngine): + backend = WhooshSearchBackend + query = WhooshSearchQuery diff --git a/djangoblog/wsgi.py b/djangoblog/wsgi.py new file mode 100644 index 0000000..2295efd --- /dev/null +++ b/djangoblog/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for djangoblog project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoblog.settings") + +application = get_wsgi_application() diff --git a/docs/README-en.md b/docs/README-en.md new file mode 100644 index 0000000..37ea069 --- /dev/null +++ b/docs/README-en.md @@ -0,0 +1,158 @@ +# DjangoBlog + +

+ Django CI + CodeQL + codecov + license +

+ +

+ A powerful, elegant, and modern blog system. +
+ English简体中文 +

+ +--- + +DjangoBlog is a high-performance blog platform built with Python 3.10 and Django 4.0. It not only provides all the core functionalities of a traditional blog but also features a flexible plugin system, allowing you to easily extend and customize your website. Whether you are a personal blogger, a tech enthusiast, or a content creator, DjangoBlog aims to provide a stable, efficient, and easy-to-maintain environment for writing and publishing. + +## ✨ Features + +- **Powerful Content Management**: Full support for managing articles, standalone pages, categories, and tags. Comes with a powerful built-in Markdown editor with syntax highlighting. +- **Full-Text Search**: Integrated search engine for fast and accurate content searching. +- **Interactive Comment System**: Supports replies, email notifications, and Markdown formatting in comments. +- **Flexible Sidebar**: Customizable modules for displaying recent articles, most viewed posts, tag cloud, and more. +- **Social Login**: Built-in OAuth support, with integrations for Google, GitHub, Facebook, Weibo, QQ, and other major platforms. +- **High-Performance Caching**: Native support for Redis caching with an automatic refresh mechanism to ensure high-speed website responses. +- **SEO Friendly**: Basic SEO features are included, with automatic notifications to Google and Baidu upon new content publication. +- **Extensible Plugin System**: Extend blog functionalities by creating standalone plugins, ensuring decoupled and maintainable code. We have already implemented features like view counting and SEO optimization through plugins! +- **Integrated Image Hosting**: A simple, built-in image hosting feature for easy uploads and management. +- **Automated Frontend**: Integrated with `django-compressor` to automatically compress and optimize CSS and JavaScript files. +- **Robust Operations**: Built-in email notifications for website exceptions and management capabilities through a WeChat Official Account. + +## 🛠️ Tech Stack + +- **Backend**: Python 3.10, Django 4.0 +- **Database**: MySQL, SQLite (configurable) +- **Cache**: Redis +- **Frontend**: HTML5, CSS3, JavaScript +- **Search**: Whoosh, Elasticsearch (configurable) +- **Editor**: Markdown (mdeditor) + +## 🚀 Getting Started + +### 1. Prerequisites + +Ensure you have Python 3.10+ and MySQL/MariaDB installed on your system. + +### 2. Clone & Installation + +```bash +# Clone the project to your local machine +git clone https://github.com/liangliangyy/DjangoBlog.git +cd DjangoBlog + +# Install dependencies +pip install -r requirements.txt +``` + +### 3. Project Configuration + +- **Database**: + Open `djangoblog/settings.py`, locate the `DATABASES` section, and update it with your MySQL connection details. + + ```python + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'djangoblog', + 'USER': 'root', + 'PASSWORD': 'your_password', + 'HOST': '127.0.0.1', + 'PORT': 3306, + } + } + ``` + Create the database in MySQL: + ```sql + CREATE DATABASE `djangoblog` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + ``` + +- **More Configurations**: + For advanced settings such as email, OAuth, caching, and more, please refer to our [Detailed Configuration Guide](/docs/config-en.md). + +### 4. Database Initialization + +```bash +python manage.py makemigrations +python manage.py migrate + +# Create a superuser account +python manage.py createsuperuser +``` + +### 5. Running the Project + +```bash +# (Optional) Generate some test data +python manage.py create_testdata + +# (Optional) Collect and compress static files +python manage.py collectstatic --noinput +python manage.py compress --force + +# Start the development server +python manage.py runserver +``` + +Now, open your browser and navigate to `http://127.0.0.1:8000/`. You should see the DjangoBlog homepage! + +## Deployment + +- **Traditional Deployment**: A detailed guide for server deployment is available here: [Deployment Tutorial](https://www.lylinux.net/article/2019/8/5/58.html) (in Chinese). +- **Docker Deployment**: This project fully supports Docker. If you are familiar with containerization, please refer to the [Docker Deployment Guide](/docs/docker-en.md) for a quick start. +- **Kubernetes Deployment**: We also provide a complete [Kubernetes Deployment Guide](/docs/k8s-en.md) to help you go cloud-native easily. + +## 🧩 Plugin System + +The plugin system is a core feature of DjangoBlog. It allows you to add new functionalities to your blog without modifying the core codebase by writing standalone plugins. + +- **How it Works**: Plugins operate by registering callback functions to predefined "hooks". For instance, when an article is rendered, the `after_article_body_get` hook is triggered, and all functions registered to this hook are executed. +- **Existing Plugins**: Features like `view_count` and `seo_optimizer` are implemented through this plugin system. +- **Develop Your Own Plugin**: Simply create a new folder under the `plugins` directory and write your `plugin.py`. We welcome you to explore and contribute your creative ideas to the DjangoBlog community! + +## 🤝 Contributing + +We warmly welcome contributions of any kind! If you have great ideas or have found a bug, please feel free to open an issue or submit a pull request. + +## 📄 License + +This project is open-sourced under the [MIT License](LICENSE). + +--- + +## ❤️ Support & Sponsorship + +If you find this project helpful and wish to support its continued maintenance and development, please consider buying me a coffee! Your support is my greatest motivation. + +

+ Alipay Sponsorship + WeChat Sponsorship +

+

+ (Left) Alipay / (Right) WeChat +

+ +## 🙏 Acknowledgements + +A special thanks to **JetBrains** for providing a free open-source license for this project. + +

+ + JetBrains Logo + +

+ +--- +> If this project has helped you, please leave your website URL [here](https://github.com/liangliangyy/DjangoBlog/issues/214) to let more people see it. Your feedback is the driving force for my continued updates and maintenance. diff --git a/docs/config-en.md b/docs/config-en.md new file mode 100644 index 0000000..b877efb --- /dev/null +++ b/docs/config-en.md @@ -0,0 +1,64 @@ +# Introduction to main features settings + +## Cache: +Cache using `memcache` for default. If you don't have `memcache` environment, you can remove the `default` setting in `CACHES` and change `locmemcache` to `default`. +```python +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '127.0.0.1:11211', + 'KEY_PREFIX': 'django_test' if TESTING else 'djangoblog', + 'TIMEOUT': 60 * 60 * 10 + }, + 'locmemcache': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'TIMEOUT': 10800, + 'LOCATION': 'unique-snowflake', + } +} +``` + +## OAuth Login: +QQ, Weibo, Google, GitHub and Facebook are now supported for OAuth login. Fetch OAuth login permissions from the corresponding open platform, and save them with `appkey`, `appsecret` and callback address in **Backend->OAuth** configuration. + +### Callback address examples: +QQ: http://your-domain-name/oauth/authorize?type=qq +Weibo: http://your-domain-name/oauth/authorize?type=weibo +type is in the type field of `oauthmanager`. + +## owntracks: +owntracks is a location tracking application. It will send your locaiton to the server by timing.Simple support owntracks features. Just install owntracks app and set api address as `your-domain-name/owntracks/logtracks`. Visit `your-domain-name/owntracks/show_dates` and you will see the date with latitude and langitude, click it and see the motion track. The map is drawn by AMap. + +## Email feature: +Same as before, Configure your own error msg recvie email information with`ADMINS = [('liangliang', 'liangliangyy@gmail.com')]` in `settings.py`. And modify: +```python +EMAIL_HOST = 'smtp.zoho.com' +EMAIL_PORT = 587 +EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER') +EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD') +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER') +``` +with your email account information. + +## WeChat Official Account +Simple wechat official account features integrated. Set token as `your-domain-name/robot` in wechat backend. Default token is `lylinux`, you can change it to your own in `servermanager/robot.py`. Add a new command in `Backend->Servermanager->command`, in this way, you can manage the system through wechat official account. + +## Introduction to website configuration +You can add website configuration in **Backend->BLOG->WebSiteConfiguration**. Such as: keywords, description, Google Ad, website stats code, case number, etc. +OAuth user avatar path is saved in *StaticFileSavedAddress*. Please input absolute path, code directory for default. + +## Source code highlighting +If the code block in your article didn't show hightlight, please write the code blocks as following: + +![](https://resource.lylinux.net/image/codelang.png) + +That is, you should add the corresponding language name before the code block. + +## Update +If you get errors as following while executing database migrations: +```python +django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")) +``` +This problem may cause by the mysql version under 5.6, a new version( >= 5.6 ) mysql is needed. + diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000..24673a3 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,58 @@ +# 主要功能配置介绍: + +## 缓存: +缓存默认使用`localmem`缓存,如果你有`redis`环境,可以设置`DJANGO_REDIS_URL`环境变量,则会自动使用该redis来作为缓存,或者你也可以直接修改如下代码来使用。 +https://github.com/liangliangyy/DjangoBlog/blob/ffcb2c3711de805f2067dd3c1c57449cd24d84ee/djangoblog/settings.py#L185-L199 + + +## oauth登录: + +现在已经支持QQ,微博,Google,GitHub,Facebook登录,需要在其对应的开放平台申请oauth登录权限,然后在 +**后台->Oauth** 配置中新增配置,填写对应的`appkey`和`appsecret`以及回调地址。 +### 回调地址示例: +qq:http://你的域名/oauth/authorize?type=qq +微博:http://你的域名/oauth/authorize?type=weibo +type对应在`oauthmanager`中的type字段。 + +## owntracks: +owntracks是一个位置追踪软件,可以定时的将你的坐标提交到你的服务器上,现在简单的支持owntracks功能,需要安装owntracks的app,然后将api地址设置为: +`你的域名/owntracks/logtracks`就可以了。然后访问`你的域名/owntracks/show_dates`就可以看到有经纬度记录的日期,点击之后就可以看到运动轨迹了。地图是使用高德地图绘制。 + +## 邮件功能: +同样,将`settings.py`中的`ADMINS = [('liangliang', 'liangliangyy@gmail.com')]`配置为你自己的错误接收邮箱,另外修改: +```python +EMAIL_HOST = 'smtp.zoho.com' +EMAIL_PORT = 587 +EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER') +EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD') +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER') +``` +为你自己的邮箱配置。 + +## 微信公众号 +集成了简单的微信公众号功能,在微信后台将token地址设置为:`你的域名/robot` 即可,默认token为`lylinux`,当然你可以修改为你自己的,在`servermanager/robot.py`中。 +然后在**后台->Servermanager->命令**中新增命令,这样就可以使用微信公众号来管理了。 +## 网站配置介绍 +在**后台->BLOG->网站配置**中,可以新增网站配置,比如关键字,描述等,以及谷歌广告,网站统计代码及备案号等等。 +其中的*静态文件保存地址*是保存oauth用户登录的头像路径,填写绝对路径,默认是代码目录。 +## 代码高亮 +如果你发现你文章的代码没有高亮,请这样书写代码块: + +![](https://resource.lylinux.net/image/codelang.png) + + +也就是说,需要在代码块开始位置加入这段代码对应的语言。 + +## update +如果你发现执行数据库迁移的时候出现如下报错: +```python +django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")) +``` +可能是因为你的mysql版本低于5.6,需要升级mysql版本>=5.6即可。 + + +django 4.0登录可能会报错CSRF,需要配置下`settings.py`中的`CSRF_TRUSTED_ORIGINS` + +https://github.com/liangliangyy/DjangoBlog/blob/master/djangoblog/settings.py#L39 + diff --git a/docs/docker-en.md b/docs/docker-en.md new file mode 100644 index 0000000..8d5d59e --- /dev/null +++ b/docs/docker-en.md @@ -0,0 +1,114 @@ +# Deploying DjangoBlog with Docker + +![Docker Pulls](https://img.shields.io/docker/pulls/liangliangyy/djangoblog) +![Docker Image Version (latest by date)](https://img.shields.io/docker/v/liangliangyy/djangoblog?sort=date) +![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/liangliangyy/djangoblog) + +This project fully supports containerized deployment using Docker, providing you with a fast, consistent, and isolated runtime environment. We recommend using `docker-compose` to launch the entire blog service stack with a single command. + +## 1. Prerequisites + +Before you begin, please ensure you have the following software installed on your system: +- [Docker Engine](https://docs.docker.com/engine/install/) +- [Docker Compose](https://docs.docker.com/compose/install/) (Included with Docker Desktop for Mac and Windows) + +## 2. Recommended Method: Using `docker-compose` (One-Click Deployment) + +This is the simplest and most recommended way to deploy. It automatically creates and manages the Django application, a MySQL database, and an optional Elasticsearch service for you. + +### Step 1: Start the Basic Services + +From the project's root directory, run the following command: + +```bash +# Build and start the containers in detached mode (includes Django app and MySQL) +docker-compose up -d --build +``` + +`docker-compose` will read the `docker-compose.yml` file, pull the necessary images, build the project image, and start all services. + +- **Access Your Blog**: Once the services are up, you can access the blog by navigating to `http://127.0.0.1` in your browser. +- **Data Persistence**: MySQL data files will be stored in the `data/mysql` directory within the project root, ensuring that your data persists across container restarts. + +### Step 2: (Optional) Enable Elasticsearch for Full-Text Search + +If you want to use Elasticsearch for more powerful full-text search capabilities, you can include the `docker-compose.es.yml` configuration file: + +```bash +# Build and start all services in detached mode (Django, MySQL, Elasticsearch) +docker-compose -f docker-compose.yml -f deploy/docker-compose/docker-compose.es.yml up -d --build +``` +- **Data Persistence**: Elasticsearch data will be stored in the `data/elasticsearch` directory. + +### Step 3: First-Time Initialization + +After the containers start for the first time, you'll need to execute some initialization commands inside the application container. + +```bash +# Get a shell inside the djangoblog application container (named 'web') +docker-compose exec web bash + +# Inside the container, run the following commands: +# Create a superuser account (follow the prompts to set username, email, and password) +python manage.py createsuperuser + +# (Optional) Create some test data +python manage.py create_testdata + +# (Optional, if ES is enabled) Create the search index +python manage.py rebuild_index + +# Exit the container +exit +``` + +## 3. Alternative Method: Using the Standalone Docker Image + +If you already have an external MySQL database running, you can run the DjangoBlog application image by itself. + +```bash +# Pull the latest image from Docker Hub +docker pull liangliangyy/djangoblog:latest + +# Run the container and connect it to your external database +docker run -d \ + -p 8000:8000 \ + -e DJANGO_SECRET_KEY='your-strong-secret-key' \ + -e DJANGO_MYSQL_HOST='your-mysql-host' \ + -e DJANGO_MYSQL_USER='your-mysql-user' \ + -e DJANGO_MYSQL_PASSWORD='your-mysql-password' \ + -e DJANGO_MYSQL_DATABASE='djangoblog' \ + --name djangoblog \ + liangliangyy/djangoblog:latest +``` + +- **Access Your Blog**: After startup, visit `http://127.0.0.1:8000`. +- **Create Superuser**: `docker exec -it djangoblog python manage.py createsuperuser` + +## 4. Configuration (Environment Variables) + +Most of the project's configuration is managed through environment variables. You can modify them in the `docker-compose.yml` file or pass them using the `-e` flag with the `docker run` command. + +| Environment Variable | Default/Example Value | Notes | +|---------------------------|--------------------------------------------------------------------------|---------------------------------------------------------------------| +| `DJANGO_SECRET_KEY` | `your-strong-secret-key` | **Must be changed to a random, complex string!** | +| `DJANGO_DEBUG` | `False` | Toggles Django's debug mode. | +| `DJANGO_MYSQL_HOST` | `mysql` | Database hostname. | +| `DJANGO_MYSQL_PORT` | `3306` | Database port. | +| `DJANGO_MYSQL_DATABASE` | `djangoblog` | Database name. | +| `DJANGO_MYSQL_USER` | `root` | Database username. | +| `DJANGO_MYSQL_PASSWORD` | `djangoblog_123` | Database password. | +| `DJANGO_REDIS_URL` | `redis:6379/0` | Redis connection URL (for caching). | +| `DJANGO_ELASTICSEARCH_HOST`| `elasticsearch:9200` | Elasticsearch host address. | +| `DJANGO_EMAIL_HOST` | `smtp.example.org` | Email server address. | +| `DJANGO_EMAIL_PORT` | `465` | Email server port. | +| `DJANGO_EMAIL_USER` | `user@example.org` | Email account username. | +| `DJANGO_EMAIL_PASSWORD` | `your-email-password` | Email account password. | +| `DJANGO_EMAIL_USE_SSL` | `True` | Whether to use SSL. | +| `DJANGO_EMAIL_USE_TLS` | `False` | Whether to use TLS. | +| `DJANGO_ADMIN_EMAIL` | `admin@example.org` | Admin email for receiving error reports. | +| `DJANGO_BAIDU_NOTIFY_URL` | `http://data.zz.baidu.com/...` | Push API from [Baidu Webmaster Tools](https://ziyuan.baidu.com/linksubmit/index). | + +--- + +After deployment, please review and adjust these environment variables according to your needs, especially `DJANGO_SECRET_KEY` and the database and email settings. \ No newline at end of file diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 0000000..e7c255a --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,114 @@ +# 使用 Docker 部署 DjangoBlog + +![Docker Pulls](https://img.shields.io/docker/pulls/liangliangyy/djangoblog) +![Docker Image Version (latest by date)](https://img.shields.io/docker/v/liangliangyy/djangoblog?sort=date) +![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/liangliangyy/djangoblog) + +本项目全面支持使用 Docker 进行容器化部署,为您提供了快速、一致且隔离的运行环境。我们推荐使用 `docker-compose` 来一键启动整个博客服务栈。 + +## 1. 环境准备 + +在开始之前,请确保您的系统中已经安装了以下软件: +- [Docker Engine](https://docs.docker.com/engine/install/) +- [Docker Compose](https://docs.docker.com/compose/install/) (对于 Docker Desktop 用户,它已内置) + +## 2. 推荐方式:使用 `docker-compose` (一键部署) + +这是最简单、最推荐的部署方式。它会自动为您创建并管理 Django 应用、MySQL 数据库,以及可选的 Elasticsearch 服务。 + +### 步骤 1: 启动基础服务 + +在项目根目录下,执行以下命令: + +```bash +# 构建并以后台模式启动容器 (包含 Django 应用和 MySQL) +docker-compose up -d --build +``` + +`docker-compose` 会读取 `docker-compose.yml` 文件,自动拉取所需镜像、构建项目镜像,并启动所有服务。 + +- **访问您的博客**: 服务启动后,在浏览器中访问 `http://127.0.0.1` 即可看到博客首页。 +- **数据持久化**: MySQL 的数据文件将存储在项目根目录下的 `data/mysql` 文件夹中,确保数据在容器重启后不丢失。 + +### 步骤 2: (可选) 启用 Elasticsearch 全文搜索 + +如果您希望使用 Elasticsearch 提供更强大的全文搜索功能,可以额外加载 `docker-compose.es.yml` 配置文件: + +```bash +# 构建并以后台模式启动所有服务 (Django, MySQL, Elasticsearch) +docker-compose -f docker-compose.yml -f deploy/docker-compose/docker-compose.es.yml up -d --build +``` +- **数据持久化**: Elasticsearch 的数据将存储在 `data/elasticsearch` 文件夹中。 + +### 步骤 3: 首次运行的初始化操作 + +当容器首次启动后,您需要进入容器来执行一些初始化命令。 + +```bash +# 进入 djangoblog 应用容器 +docker-compose exec web bash + +# 在容器内执行以下命令: +# 创建超级管理员账户 (请按照提示设置用户名、邮箱和密码) +python manage.py createsuperuser + +# (可选) 创建一些测试数据 +python manage.py create_testdata + +# (可选,如果启用了 ES) 创建索引 +python manage.py rebuild_index + +# 退出容器 +exit +``` + +## 3. 备选方式:使用独立的 Docker 镜像 + +如果您已经拥有一个正在运行的外部 MySQL 数据库,您也可以只运行 DjangoBlog 的应用镜像。 + +```bash +# 从 Docker Hub 拉取最新镜像 +docker pull liangliangyy/djangoblog:latest + +# 运行容器,并链接到您的外部数据库 +docker run -d \ + -p 8000:8000 \ + -e DJANGO_SECRET_KEY='your-strong-secret-key' \ + -e DJANGO_MYSQL_HOST='your-mysql-host' \ + -e DJANGO_MYSQL_USER='your-mysql-user' \ + -e DJANGO_MYSQL_PASSWORD='your-mysql-password' \ + -e DJANGO_MYSQL_DATABASE='djangoblog' \ + --name djangoblog \ + liangliangyy/djangoblog:latest +``` + +- **访问您的博客**: 启动完成后,访问 `http://127.0.0.1:8000`。 +- **创建管理员**: `docker exec -it djangoblog python manage.py createsuperuser` + +## 4. 配置说明 (环境变量) + +本项目的大部分配置都通过环境变量来管理。您可以在 `docker-compose.yml` 文件中修改它们,或者在使用 `docker run` 命令时通过 `-e` 参数传入。 + +| 环境变量名称 | 默认值/示例 | 备注 | +|-------------------------|--------------------------------------------------------------------------|---------------------------------------------------------------------| +| `DJANGO_SECRET_KEY` | `your-strong-secret-key` | **请务必修改为一个随机且复杂的字符串!** | +| `DJANGO_DEBUG` | `False` | 是否开启 Django 的调试模式 | +| `DJANGO_MYSQL_HOST` | `mysql` | 数据库主机名 | +| `DJANGO_MYSQL_PORT` | `3306` | 数据库端口 | +| `DJANGO_MYSQL_DATABASE` | `djangoblog` | 数据库名称 | +| `DJANGO_MYSQL_USER` | `root` | 数据库用户名 | +| `DJANGO_MYSQL_PASSWORD` | `djangoblog_123` | 数据库密码 | +| `DJANGO_REDIS_URL` | `redis:6379/0` | Redis 连接地址 (用于缓存) | +| `DJANGO_ELASTICSEARCH_HOST` | `elasticsearch:9200` | Elasticsearch 主机地址 | +| `DJANGO_EMAIL_HOST` | `smtp.example.org` | 邮件服务器地址 | +| `DJANGO_EMAIL_PORT` | `465` | 邮件服务器端口 | +| `DJANGO_EMAIL_USER` | `user@example.org` | 邮件账户 | +| `DJANGO_EMAIL_PASSWORD` | `your-email-password` | 邮件密码 | +| `DJANGO_EMAIL_USE_SSL` | `True` | 是否使用 SSL | +| `DJANGO_EMAIL_USE_TLS` | `False` | 是否使用 TLS | +| `DJANGO_ADMIN_EMAIL` | `admin@example.org` | 接收异常报告的管理员邮箱 | +| `DJANGO_BAIDU_NOTIFY_URL` | `http://data.zz.baidu.com/...` | [百度站长平台](https://ziyuan.baidu.com/linksubmit/index) 的推送接口 | + +--- + +部署完成后,请务必检查并根据您的实际需求调整这些环境变量,特别是 `DJANGO_SECRET_KEY` 和数据库、邮件相关的配置。 diff --git a/docs/es.md b/docs/es.md new file mode 100644 index 0000000..97226c5 --- /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/docs/imgs/alipay.jpg b/docs/imgs/alipay.jpg new file mode 100644 index 0000000000000000000000000000000000000000..424d70a2ffbb629b481e0c27d72d6076727e8041 GIT binary patch literal 17961 zcmcJ%1z1$w*Y`hk4B$wLgu@LetspQo3`$A2q)LZ$NQk5;NOyN5ASECmq9ENJ(p`cQ zD)pb4GkAO7&+~hq>-oRe3+I|^=Ir5|9qa79)@OY;=i}#dAjmywIcX3E1_*?K_ywI$ zf$o43WvM?$PLN;@xT5#{{Xs-kI{uOfQ9iF2=g)q z)@6+I7SL4?2onog+rNKsu&{A4k!5fQ2m=cPlMoLN3mX#)goSJpCKfi%Wl{e36aR6Wg z2=J#H4*&7Lt&InbnnzMz%c1mDyZ3W;?fm)p*bIn6y{af(4(q`cOXe|8ol0^lNCdh? zO=jBiI)l!k51Zd@U9QH$zDXhxvG^|X9EAVBZ0_(rf6f7)V$fCy@2uB{*$5kndHj3q zHgfAl>0~t2*0S$*Jzun9IWztHYf2D&jcvC4L5Z=?SLIx0Mjy9wp!@t%|3xLyeU7!y zgzokbpwA^v32=dK&jtprUtAK79=rc?ksTVdEV+b_?LJOEFsvS|7G$^JW0%ej7=Qmo zKEPhHfB)p{IVL#+tfFAPAdf4uCgm>}HX)>{wlrDWeknv-vAEU|o+LTA@Xp5IQxvxW zf9ZS&t|eGLc)j`wiEOL$Wc>>!>Kslk_Pmj4K{l-tCf?!Zfj5S$29j$zYLuJu=gs-0`X+gm94OHxcN|W1iINFu+ zdk+p{Dp>xNWv}b(UhSp3MyNUv4N}Ha3|Z~aMgn!XEvu`Ks-~O`B@bK8=g-qL(NC7~ z-YPdRj_=@D#z|5?AoAUU3Ah#u4Cd>(ulOrGPy8G!G}Xszd@t2zHHnx<$963Q(HoUl zH8$-;MvAB(JYdf*fK``#tQRLIR8Pj@J=WVO1#X`I;2ae8VPg@G-+jV}s%wNu)F5LvHIN>&@_N(_(VxD!u*Q1Ly5c{b5%R zuEsvRXr@`mQGh4ihY}u~xSf}M;+e8!$4~B>r}yXJV{_v0r7Hb$o7Rb`B8zy!>hOOa z#NQSEmkp>5S*p6XQCN)x3b{|VPlB4?pM#E!3gvU9R%unNBLbk104Qm_w^VrFn)+R| zf#ItkgYP^^*(JdAeq>?$Jq-hks{6k@1c%D4xm&Vu(EW|K&f=GL$JbYmhw|eaRCqMXXA+S zF+<_l`s;4%8?@`hAKq@yYrh^``CcESk}(K$hJm$4s~RJBEiFy!>`qGwK1K@X%bt_h zZoQNr%+6Fi0vIsCPZaDT9N1DxQt`U&C>*~G(Jay4%fFKk|4!42TUh5;V$rf*F!LEa zExYi#=9Xbb_rkkWgEqv2i>!@hgf9gS(XM8N%$w<(xO1M89sy9a@%xI`I7_>q5=!`^ zpVd6JtD>aW7~OE#E6K_CQu*KShFB_=G&t#Gr{eS04kqilt)NfjK!^AT@}2y37v#36 zC>%^#oY%yR-AdG*u<>oaaKDGQ6!A`K7&^2X);NFuiAP$1vLo`V!~bC_I{VoFWmN=I zB7Iz!reW0w?)ck4bl+{`ddKa6S+^ZV{fdM2(>Y0$85tu0mkElsjyZxLa- zwP+}ngS2UEWDSD@$gozuf4%?d=RLR`nWF16+L46olzKwcwoEBEkJgf5w`76FWz>ab z>@0Q|>RlrBpVIp>Xk!PdWLLEIe5Y8lKxvALE-Ee3Qm)S$ zcZ+qw6x>S8N&Sk)n4)a{Y~(X@deaNuQ+$Y#&hZZ?>EE9$1NDA5X>+$Q3Q(O8EF}ta z-(O6{O^d3oHXSF1!34Ditx>a7N`|(j&NodByf;h4SixmDvApU$3O`72w^D{$pu1*< znfN%;Swq2T=6C1ptQso$YZ^=^1+a1IqCz+OZ7 zW2sUcv`hZ92i$6WNesk+UW9n>ZJ$z#i)TtaM?ZHFHx4NSzY5Ml^h^8Af7;Gfg!O8@ z%?#AFWV9J;%)yQsABs+Y!3%~YF8tkBV2Z9AGncoXVCJ_}9__B=XIGl#7n$Q01C3c>XR}&qI@kegI0gia4aYW2WaI*E|-6jR-3{_TFOLyl?rE7*b4^+wDB<1k2Pi zu|?I06_**St~>KZ@%(kQU*_Qs_->50PSmibm{v-dm@j6w`t9efKS>li$@@tAWvNCPAB{9PKcIBxw2cCf&Y)3KbSSjehi~3PL?(q>+ zW;AbXnq0}j=~YleN=}|YlIxt_iW&*Hd`VAPExVTUH+el8 z!_Ck7J_h6U|8+Rf)`ydKkNtIr6LiB_&P({B zk_t9W+dC(vS=HSY75r}u7eEcqRA7=A4a^6l;Tj1t{@xYDN6?1>$@JcKPnNl}Q-;-p zWI@6_V0;zLzLCN&oMT^}kk_CJao7O|BQNEE!}uJuH0%E&UVQJ%t~BG>$~ovGuCoV| znDj28N%B<}yS0b&&d+*&h)xKP1hd~A>G8P&!u;kN3@Owea}l{@cEaAT?`l-uCgc?M zwZk`k{--o^6BorS5&J3Rx@6-6NtRD`4$Pgwc);UL##;f*_)Q|IM3faQsIQ}6{JmGb0vTfr_!5YNIc`yZ!{U>!+^4N;*gf_u z+)Gq^rS*LCxXPLFpS&l-0v`~cgRDlKx!oQgtM<3fS8l_j*GzY353^C_)u}{=G-AW3 zVil8L)K6ij1*qZ@^E*_5ebscRVrntqGD67mVja|FWKiY*<84Z$=wDGa``D_XZlNs! z;=-KsK@HG&J#rzz@+9bam`w1&)YhpQc3aBfEL&_j%6fWsaDksDG zXWXxH)eo`3hWA;(Xjd1s9GoZU2b>J&#Bgwf2c1l^BFk$9TS7u%DVw7GUGq)bT3cg6 zy5m!fuae;Hi*DUjqNwJRZ*^ShWSLy$E2Wwts13>0U(ed3KH@mdXPnSu)LrGvc;y4b zh+y;Leb0EdM5fuwP!#iW8twq~O=qhyD(^0KrIEKY{kZ4yQ_@n7+$`=dV@u|YDCwuc zuAe_APk#2_#TS;_9u-`nrHqc82yB^mT;ZE7%-F`~F`~A+Hsn27&6)PsP11_Rmi{Mz!YOo3%p63Zbg)S=VstJ2w`3CY0gGouNm!5AnftgC-X`F8>lA80Oi&~R~q=e z3Q*-49s9^DsiMktdr{W`ig~<{ml+0bREfGw*gtL~r%3LX_m}aLO}can;9_M&+?O4K z;@u?)5YEHD4yv1O#_}n);9MoZwT32_G?&$8BVS%8L9B(QuO0_ShFebs47uGuKtJhl z)^070K}GMi8OjoTo|}HMtzT_ES%sJr^faXrhwaNnShecIo;9|5j?RruYboOMrP>mE zwKBamoM6*Egh=Dly63hdo@Tghx08;3o4_=e2x0$0E#DDEv?MNNfO1lW93w{0jq4A5 zG(B>DC4clbIey3aB1l_BJugjQebIUvP7Hb#?wDGAS+u#tWof0ok|Ife=7|H__Ve7P zjtz*oB*gzy!t27Eq;t?f1E(&8rQGEt_$| zYlmKcZDdzzY_bC3g;jC_G)!(WWcoG- zor4DLD@UD4rSxc0rULb|ZyNPyPzVFQbiT`71qbU?hif=${c(bbNJoH*lxu4no~q3; zX*Qy?BC>+q`$6vN1h8$++qiAN7_8wmefS#MQ-yD7WgV&)RxYx zl@4hH*zGC@1ujPv?E19*E6L5>Dq6)^riLWcr?8^WpZ&H@-1DqIC1kVDpk$yk{g`R(rjXHWGKF2nS{|#3mvsc7~L2C@%^54rm3iUmidV-jaIICiIDpP z1IDDTX2zO12$y7Xk#b=JBk~1Wu58(*3^ul);*$@{-8V>7{z=)u10qfD<~ z<$kiKirnyBApd7$5oS&9QtNU=PJs5v$+t*{WoW`=1TYhHL;3g^_B`)k6CKfy7{;aD z-^lVzu-DyHobXh+P034TzS!fyN$yO<$DMAO$YatM{r2Fg<{kUPBMRMrjL022tPf-W5{54<&F&|33lqgqHodXps z-?P!lE=Vm4{SZP^`yFnG4v>hNP1X&^5xpAPT!wwB<)iC7cFEdp#czWG_$z4?hsZ$0 zjGqm%eWZY?U43LoPDf>Z{)&Rjn2G2ZR{@K;UrCf`;Jh0QYZ4-QK|_l8t4KA}tIJ=t zyR5FMnDryD)!*Si4*x3H=(aaIKSyVTOl9piU4EKL;uf-T73b&J2de51_rvPJJTIt+ z5YVOHKts{=4kQrMA zNhlJHr=l{auZQqU=7zFX*MwOBM2AYHNX7!r;Tysfoq$RB)k+O8X{uB|-^T*b7Id-C0(1;!-o(K@D4Q14QUZXu)b) z_;GFO8Ho!&svK$#a3*xfSfJ85iLanZ-}UNMWw=4GPH{#WUQ3&&8gG^B>bSp{x2o0_ zFt_ec#4^qL*M8Gt`DedgV7DQTo|3QBu3;D$CdVH|!{)RS%^m}PIRu4drMaz7(lOMM zIhFyf=E_w26J>!5^wGUIh=I=*cRO!v24e8<9x4Q|*S@aC4vaTyF#;rQu*QYvS^w|sa(H+qzzI;oW2P}O?c%}7M*JrGlw)O z_zQl6l;$Y(IS|U`Qj=!E+pd#hsb13XU7ELWbjCenh{5c6p}P0RjC%=>+=P35cE%HTcpxT5MVeZb!wY(<4N+0K;14l@{kP_&gs;peAZD|#x#s7f z@@sc`FuTxUN?Kfh6Gt_XXShwX`+!awyO@6zwq@$`+>WIK!agZ8x7WW&| z|1u*^1+|JsRapuq+jkB!5_^%fbf6=CG{P@&+fZ=Emz1nGuxC$apElN9WuUGlc$ELF zo7Ufh;585m$LmxzYUgl9R+KO4ubkXefHy$lz{;ndIh64;bfFX-Gy*YZ1_FW@meC}z zjfRv4hJJli_aTgh^TL9zpeS@klDX0e?91~>KTq`h*LC~Cv@n6tFo)n2y?|rxn-iS= zgW)PBD&Wi`&^r~b-LgmJ{mu+CmsxPffgu`cvsY4t366A|BS%q_);>iE?(KL9lACL6 zQWO+MRow?dOglO;W0%bBm;8Bi^N@=-I~>62ls3YO+t>nTP@?1r14)Pv@*wT9+zCsA z-SXLDFRQOuBI>X3vi0(67Al`vXH7YZG6;~K^Nj-H-*D5gnb*FsO9jB~}z%)6> zDwD5T)C!=kSi_X+&}Ive8HPqfsdmx2pwj@xIS5k6ed~}lIWoV|QCgEZH_~AEwB#3y zyey1%)rU^@KAn`yX02{FqS6!uQXRJGo?BR&+uT)*%$nO;tUY`^uf0aVOA*?% zUxRN``wje900=7!0lug&cYC>>cx<{JFr}<&#cm3Dz}qQ7AY9SR?PmK1XdAlM`X(Rp zRBu~Q@z3Gy3TB{PL&WrS!A-yb7mwh48u?ZNYsyXEMb-rtg9C6-1iIS`v8M6s2N@!K zz%apn|5W~R29qp({#geqJBeJdmgS?`W17w`k$8bo+)DDxZjDCd z*yEOiZ;Y-YAX0?Jy`PKLDfmu4P~UhqVoAUZvMtrcimr3}EV&#lX-D|tB0(mf5yA7g z-ax&e8{pGl*Vl3C^I+`)F;t1xQcR)7dhQOj;ByecOZGp!%>#T%BJ{jV3B*2>0I>wf zFZoqd98Gyk<4bPsik;4A=1b&)_k{l536FDm^&EuurVhnLc))kWoUlUjwd5rF2GSkK zFt!|R)4HPL#@Te^xSVTSa^D>P$^wcW8H#np@eA&_^jI_`H?d3H_GY_^0?+t7&xPKs z*n%_8K@p8(Cp=80z3Revir!r!l7!`NW(W@-{3yeEr5*0>(j|58GfHZ1~nX4|P|@0fR4T1ei%jLJ}3Z1bs%(}>LE&~BaNL}TVt6FwIaZBuZ<^iSe( zDxAK(froKlA_~$r!8&nh zoh!X77`3?-=^H{j`=ia`$LF9kFKxTFYl9m_+G-8lJBKgdFH;D&XmYo2?il;BodP3J zE+tOc4KkZ?XNCUez*-J}Lv<;aL{2I7Wy|)(H8N+Y3 zy79~P(LFGazr3OaPmw+@jB{*DTMZ1BkM7tY+XpXKXNJk#3MpZ_cDUU9_EGK9V#oE1 z)W`bRBU&=IEvD;-xR!@CBiEH4qvl*Z5@gy&j|>%v)MoQ^wogUW`rOpsLn6|m7{G%= zBs_>34cH3}uN;~FbsXb7sUh~C@(c|4IOGvB42|0jD~a>~gu2UR>^bL`SHiJVX*cwX^i%G(F9wBOE2w%zUNVPg(*3&2pYh7{Uqh}B zf?c-z5@RiUu|sGx9giLoy-KpDjvy*dyva0E_fBN}i%VD35k)(-il)p%S`7bG(%Jr* zd8a_BPo|OK3?&U*R%!AQf}L{PHv0wYo>=FgrgKnVky`S76ATq4JM)nz_UP49E!)Dy z1ko@mADM4uQ=B{+)dN+HwIIXktdpWtM*7a$loi1e>t?1`rG&(goWS`lJN5xZu;P58 zOsn(t;Q3Q&udW%?(2$IJ3>C!24)T?@<8S@IK1K~|A%WT`0@3F163K3nwwouQG*kG-|!%R z0BLYx8U4&$m0uiLYEIg>g^FweJ&fd^@JpHqqfyT&1q|!*)SuwF-UhOfSC@0y2WQbz zqwpUr8d5kmk|fO|Uxxj~Wj2Ni5^davfWXDWeA1;bacm5)cBYd4{GaB2-PE}a=OEQ{ zkmJx8%9+=ZF=r88&)vIr#F!V~;yqm}N%G6`smy6R>KqsOaD+=zV5`^IY%?Am3Zyv? z{s=#gek^m^a}EkH65p{qfvOM5FNp8x>dI#GmXp!Qabic^Uee&cb_6@S94b_^f6M-z zxY-H)R_YoJKpP)jN73&q0C;V1HHuzDQrD0t&lHHxL6+#8P|NUO18zy1sPyIF=T{|hC34B;lDL7AHt}gYt9(6q1BQCP9)WR`g&q#~<%!Q)y zIqr|vGrN1t)p-ng7;U&d^PedizP7PN*xo*(m3Xc7Tu%`S3dA@ns`0;xJyNiM`tEtnK(Yn`65H1EyAbDKYcTEv%@%Ae)S={$inbWS`qz9J~gYx*XeBb8m4>VxM5k>a+az-Vi@mjW1(wKn1`(NK2W3>_A zbn>3(&h{CS`0M)abUQ;;(s)6RvkkF5BfC_aP#>z_;=(Rc(0>jnYk{T5bg3D|82{;d zAR6OqcrZPn^siHjHdZP*C8FgDpJ>9Xzu^JoE2gr--}0Z5zH%se_>vdb-)qjK3C6c0 zayIj|Q*>{_e_*N4)w|3Qdl6;5a(m1Z_TQg+G&e2!KPkf1d`Er`;@H*k=dDTK z5Z_UB$k#mw?d^&m9@9+>1l{a|}PhK<52nyU#D%8*uf>__Hjq7dHS zSweNH$-xeqgu|IJ@XMy%cv2t9@;hKFwq&w0kbg6*<;|156<^Fcz}r?Ak;n6@3N_`R25uwzIZIQ_6a&M3dQTUdd8VNiWffn(4M$wnEdu52(|pKV!+adX0m`P z`y&$Cx8FFAom93khy8Xb@MZOn;&U$NG7R=@G`_*-Hu76oMFmuPyq;wxs z6$vHYdbIZSRA(r?aIDqnBgL_Zft10wQ^GUiG}Zq>uF70yrQ({zJbWe?mOb5jMuL)0(afa+?<+blAg z3M^Ms85DIRbft{H5j}ik{q8P*m$~9)0VM&k#+oCxAINTwP(%9y`LF-kwQJ-32I=9v z_+$W_j1k(pX`(NTY4^}9-P%h<;Exmr_Wo~&pcC+_bu$y7=uCtv%CguFQ0`8wayGoHK{XGa)$1&vZe;Kxx~N!Y7TmZ@I7Pm52@dU zoS2AU5-J*S-6p+cbSoZqf4|gL>L@wTqHpy# z?6q4zL8)*yX1I$e+%DsO`~YI}546v%?wS%k`jSvpWMFX)>Zm!<@`$VMQ}eoqVK7~s zRJu}1Cp^1*4JZBTSjznuYF8ZYSEsB$=wOlRNCjK-vt(}!e1;P53 zGC}#bnxh>>l5f5>c8=*L!ajbo!+K34UENK$1?m@dRt)KKv%ozKMxecs`EC{CFlV4U za}Zfaw0Q^ycP7b|ozi?9$;34SIA-Ej^;~krVg5o9&5N4aEVQyDWf==>x*e5U_6Yl- zZ(C9>O46iZrHe`j`|Bd2P2eaTL4aOa`tJ_!mL2fP`%LeUUy2q3%hliH4OwE>HpuAv z_NCdBE+qp!wfxD5x+eiE;d2~43aOU?6=sm{$8zOHG$zVXu|Ry&gwheg{7ULh6s~BC z;T(x_@ZXA+m-5`abmt(wpLrG%Nf|~d^e=A8rC0J#9S`G9ByCN#F^d8OCc+uvVPejY z3&*oaVu+RVGR_9NVP9w|{MaQ^2O7FR$kWA~5M~Edh1r~gdcA{H)tRx?-w8hQG@SlH z9rxHuqpF+-|895}W93tdLn2DwDM#(Gf}6PO6;H{3EJPotTgmFarz(EQY>J3&CN=_Kq^#>$8&UsxPZm9rX>VNBQ(o|F|NCmWkMAjZ^cx9zsoB>13J zXpvha*4}Jx9h@L%iuDY;&B{_n6X%ZnLu_1quD_P()CQ&QbtUi|)~>R-Y&Ua6jpjJn zir(DilDe(INh6{5usqR3Q27I!lO7C)o5V9aeUi)WIekPW5Ve>Rb0>j;GF!;96r1*1 z{%IjM2i=K#7LZ#u^EG4kZwlvYsZz)Y8UE~*_vERg>r676YfXL5ns2G`J`T6hpVeh5SO>Kz=%e$^z|b+z15lb%k|YI@ zbkrBda|9+SH50%r5h-T|Y>G*Q$HO^IsXEa)f_BKXpJn-`CY!fuD;a)|5eOq(eEc$D zZl(4S@61iSq;KfDqZkatM}FIKR+-2yWLh2(cV0+1!2nwWpi*HmM72kyTVTrV{bs-H z=Do~qPA6YH0a%e0Ku;MdhBtOZBD4avKS4c-d+CZsc?-v8+{*xU*pZzYz1PQ zBa#C>6yqH!$RWKYSTpU}?}`wzSp$MAqIvP^b<@JNcl@*dUdK@bW*Yv_NESP=e9hFY zZ1DkosWIE5)G@k@UuAk0Lv_t14orvO;7f?R=FNAgl*SH|;jf>@#l0{WOD1c{8p%$| z$`Rt9xdm$a$-)BQFh9#w;oVtRDywu<`y+!lT%OR&3RGr29tjCuIE-++k$`Gs+@M;Q zoXW(qO}EWa%0%mz!Z?7$mtR2Bds%^Iz1{o|{Ks?QXrDlfBZ0A?z{!LPsl{PC08)Of z(IU^@7eQ)5h)Ote@R@sQC%osVwF&I*9?Z`?^b_0?pIf}fgrF}*sIck4PGmGR zYsJ@{$u(^xh0;`(abnt?lZJR3cY$Dwh2YA>l@$TQF>r7(3QgWyfZV|mW^KMagR!L! zhzI{WDf7SdgAzU9Ad|~?f6~S98rsV5bu(7FFZm`>;ByMB#+H}Y)Xh?O;hLc*<$RY> zlWGd(*nGzD3{4bh$haTyr!wn)bqq=dL%@$x=B*@#h2e64Fzm-w_9KW0fKt8S)-2l8 zk@F9{`LR)}?N&-W;(5a8%||n0Blj>B#aW18X`)$|!eQ?MSI7&RGkkgkE6z<=!HC+L za%b0wRV;esM6>1Zvc{1~7%G)dA<`T4VP=?4cV;Kr+UIvHh6nK@H{iKw zd1+B>^v;jB^vnhqW~owG%v;y6v!KC(&7hN$3w zzYXuCNV<1pWd0$|8`}e|a+Lh64sB@npb0vU*Gy}p?3-q@6631WWJmdG;%R)Ec721< zn3v*%rpKD16#If@ZInPpXXb5`%&So2gXJ=J-G|8ZIX`k%%Xyc(ANiNAA9$i9ZkQhj zm%e!foHF_0>Db-A=M_&x|25q7wDYr&e|NFWD=!vJ{yg2}F7vX<*oB{@65C zs+Ap?J)EpbRrxi_#bzQv2RB5cXoIZkx(y@&;fjP`5=P(Gh1xghyK!DZsu1Bg=poma zp)tnht|1wjBuX`lhow&6dv1-!6y)#60|g3o?@tA}w5_QyqRE;3eJhJG7qc!A|D0##? zZAYu3cab-HQPNjd%f%Eq2r=C3GXh^Y({Z9<9Ij-Ft#U|&3=u@HrMX^r%Pg(aBM$Ym zByLLEH%JmA#Ls0~>PR`^^*E03n9kKGdE0sq++GwKWX40{6L>Q4bRnoYxu_OGZ>fY{ zE)j_f4I4J|k-ML7(T2T03H}CwqO3DSUfi3+^4GsU-S}H6dION9s#g`JYGU2*o*&y` zTR?w1Wr%y=!)F2TB&cIoodLtE!%Wb>e$$(&VtvT-tO#2 z-hNY6Cz6(lfx6!nR0Z~-5*(IgeV>v%rgo(vphF*RS-4hdbxeYQ(Fyy=W7JJ(&<1NK za(y^DFL)Q!d=7e6+|E&$l^SKn|8&GLlpSGkSCeob0cS%Y}7>XECBda#?AYw#(t#=+-AnYLjn@;v7-xc%|pZB z-@25Zf6@E?iqT-1>QI}V|2}Pi)D#-7z5T*_tVDNm_fWm2J7~E{0EUH zaTS1=8oR}i)Yu5IzhuaJUQpk;{71-fgn99r)D@c@raD#Jg%rK8OP47l=598G)R@Wj z3sTPhZiV`Q96~rJBXt8Q=)!u8yhE%_RpnofgHAR5AyUT@l4pNCRG}~Y=Dj!tKLCypG0l6F-03=k8_xdFVtKtN$L;0@ zdllSZ8bb4G@{$AlXnPw?(qZ&2i;za~=DRe!%4ZZC8;W+TFN_-@m{VN{HK)4kjPA{M zXH#(!=3rgs@D?*K6N=(Bj}?rM^|%Mhm(NZSlyM4$ZhUriJrnEe) zRTrlvJqpsdr3&x#o3PF)w9dA4vIjNRNjnw|N*`)|T;=Y;n2VBrT)?}?qB7Dv%KC-k z=)n_;TisLzWGH;eJQ6`@!No#iqD9T-fedVB88xA zo;JC|uZgi!#Co3ph0}|BB{faa&67DZQZ{0o-XKATf{#ZZ%+&fF-U+AAOtAa?aLb}0l5WnG!>`?^H zx;`p{5TRCD<&pDIgyuBDu1=!sVf*15{)I(*0r6PfNrn+cCs{@i`14?)I&y!`f8JMd z*kb%Z+CGVHJ7sZ>lnL!6;R51P0M#nlTO&kwSc0l3X%OB1-+EPj7eFzDkPZFU(}W57 z5|=uiOyIL9nIqTRgi$pZPG-%!Mf-Or&w2l|+#ZpQ?4UM5&}dG?LIg_IU1eTafvAC3jwBAh% z9S0LF>sJsKN_hHwa+N=0)+^Uv9jPa19pl+^f4`NfU6>zvKq?rDO+|{&*r;1RAH`Nf zRpp~+Uw_j=Vh`;lbgJ95{8YG4e0|Of!f3Ex;VS#J=xb3=VFOFb;234CzO=o6DZq?{ zkhs2UeEwu79L22C4qkbyps>(LLEx{S&C9! zqFx9jK>9e%B;6VYNcEhXRc7t6XE0G_Z}PaJb<4OS9=lU$p?WhSV2HkccLqhdGHg(S zWrF|~p<%J>3qJo&Pz-2lNFnq^)@59eu$a4eoMPzfcAjiF2;bX5(Yk`+D%2LD|MixU zd_mo!|NBit2-hAGKj~7Iv$l)#L*f@3=0wuTv>^0Z2EcD~O@A=r&v+`CF1;pg`O#~R zdFh)!bZZ&CjU`0!k~h6o!*?3ig)3#y5Dr9yl!a%FcI?y_3y*6ZwT!Y&Gp`gzGp6qf z3!mXrO#mC4@-(282uWdko4($zc0XG5OPDmMp%ba0uuiMEql&`da93afQHT^9j7r>j zo_L1@zagwUwX-$#0jB}nxD*8LIW4%Fi4R{y%0fola}$zC&Os$7{dZ8LOg&aDDkvt* z6{|v6K&v164{d@r;P~b4$r{B*5p6*OuFfai)OxCSo1~XEHuz7)CLS2wBwbVKtnT0} zbJ+zuN1{ox6C_`^KtuQc_7gu!Q;3NTkdj=Idhi4l$%o`|>io%B4U#{JDTAC+Gv{50 z`r9cOO06j7F5xS$h}?jv{u+hxM<*_GH}}|ov}`aD>E{8|E9h-Sis-$GDh$e7|8%#h z*sG||^lCY>D`Sg)=Ma!M`(m@9#t2%1?XU1Z?;%RWm&DZEc742@DRG(@p4~zzl*2hQqqGixEB@_XUwvGfowJb6dIkeE}_PtEnQ>*cqZ@ z`u%SM63p&Hl*CkhPZP<5Rnat6d4q+|3pvTSk7jPUpIy~b1;$&&8bRd{H~AkooZ@Wc z3Ek7VKj7|!e@!Z#-&AoGi5S=*W)7$wkpT0mYKJGbx(L;WGn@GZy0J|#j@wfC+lyw3 zN@Ae*m6)Li9uo&GC(+@%(3S8&0wBto6#SQDH{VpUDCR3jjq4$J$7~--n+MaP0Njak zIHjlIG2_4!VxnDz4#Qc~FcQ(kw6`mi`Svqf62mZRuzHr__N zX|⁡O0bI!3Bi@jSTgKn>Bg&Q53II7XEA`NhoOY$25L(eK?<1>~>hujoRs}yUHVX zQTt}~MN1Zw0!xe7-aUbnm3fxd*KjwLLobx-SSZdGT`vUtB-=hS^~#Rs9K<#Wao{Zp z{kmB)_tVwwglj-W2qla4$Dx zz53|611jp`Ro8}#TnY+1OdA}SN;lGY+!=)=QY;q0b}yA~i0O^|s1#r34{5DET&Qh` z+yAF+h#H($?p6{{X zz@F@jlhUjuyW%|!{Q!~$q>$)y1Hsl$FMYS;#r=c7U7SN-8Uv-lv<@mZOXKOlXLy4C z3v?;Yh1KbtsO!ynC%cyr-`4MR8{Y~e28GXK7yRZ9{3d5(xoP=XYdX*Uy?#pU$a5>& z`JUOV_ zRl}`OH8`y;U%XD+MFBD!HxL@B`JSH_G!;0V9-A+_4Hhf%=wJ%txE{qNaHkfkLsS+h zfe@JrYreKrFKhU2`1kD)K_#LCd!v$sI$is2ee^7Am=@kq2Z-`cU(l{<8*ON_J?@@& zOR+4E3%sN-vIK-%81R}RdPK$bCrBoGF zRu$>N^0s*R^!6R919|j@|cY|A}(o`$`Onha=;(7(EQNg;0 z^sK+j)DQ>i-wCKpkXH^lH{QNw|FWJ%bUle^xtPfLdv#(gNpA7lv59GyIOXp*E+vz_!y|AkM=lB7mYXSWGfxr6#WlV5UW{v7tVn1!e zwg=v}kG!o+0qXfY-FyUozk}%&PS$ZRL^NoDuz%nVw(p)FVMPG6Ph*mgs4z0~C)P`9 zWsg_X!-)T2FkH=VqaRBu8Zkq=AX6oLSWpg(yQ^NIftdmxjx literal 0 HcmV?d00001 diff --git a/docs/imgs/pycharm_logo.png b/docs/imgs/pycharm_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2a4b0ea66469bd218774de8cb3027a9c18b84d GIT binary patch literal 132045 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 z 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

*$hI3G#u%WdV|9<`IE_VBVx2~ei~?p& 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


AewDOjh!MMu(vjQJBsiX3ZCmAui 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 literal 0 HcmV?d00001 diff --git a/docs/k8s-en.md b/docs/k8s-en.md new file mode 100644 index 0000000..20e9527 --- /dev/null +++ b/docs/k8s-en.md @@ -0,0 +1,141 @@ +# Deploying DjangoBlog with Kubernetes + +This document guides you through deploying the DjangoBlog application on a Kubernetes (K8s) cluster. We provide a complete set of `.yaml` configuration files in the `deploy/k8s` directory to deploy a full service stack, including the DjangoBlog application, Nginx, MySQL, Redis, and Elasticsearch. + +## Architecture Overview + +This deployment utilizes a microservices-based, cloud-native architecture: + +- **Core Components**: Each core service (DjangoBlog, Nginx, MySQL, Redis, Elasticsearch) runs as a separate `Deployment`. +- **Configuration Management**: Nginx configurations and Django application environment variables are managed via `ConfigMap`. **Note: For sensitive information like passwords, using `Secret` is highly recommended.** +- **Service Discovery**: All services are exposed internally within the cluster as `ClusterIP` type `Service`, enabling communication via service names. +- **External Access**: An `Ingress` resource is used to route external HTTP traffic to the Nginx service, which acts as the single entry point for the entire blog application. +- **Data Persistence**: A `local-storage` solution based on node-local paths is used. This requires you to manually create storage directories on a specific K8s node and statically bind them using `PersistentVolume` (PV) and `PersistentVolumeClaim` (PVC). + +## 1. Prerequisites + +Before you begin, please ensure you have the following: + +- A running Kubernetes cluster. +- The `kubectl` command-line tool configured to connect to your cluster. +- An [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/deploy/) installed and configured in your cluster. +- Filesystem access to one of the nodes in your cluster (defaulted to `master` in the configs) to create local storage directories. + +## 2. Deployment Steps + +### Step 1: Create a Namespace + +We recommend deploying all DjangoBlog-related resources in a dedicated namespace for better management. + +```bash +# Create a namespace named 'djangoblog' +kubectl create namespace djangoblog +``` + +### Step 2: Configure Persistent Storage + +This setup uses Local Persistent Volumes. You need to create the data storage directories on a node within your cluster (the default is the `master` node in `pv.yaml`). + +```bash +# Log in to your master node +ssh user@master-node + +# Create the required storage directories +sudo mkdir -p /mnt/local-storage-db +sudo mkdir -p /mnt/local-storage-djangoblog +sudo mkdir -p /mnt/resource/ +sudo mkdir -p /mnt/local-storage-elasticsearch + +# Log out from the node +exit +``` +**Note**: If you wish to store data on a different node or use different paths, you must modify the `nodeAffinity` and `local.path` settings in the `deploy/k8s/pv.yaml` file. + +After creating the directories, apply the storage-related configurations: + +```bash +# Apply the StorageClass +kubectl apply -f deploy/k8s/storageclass.yaml + +# Apply the PersistentVolumes (PVs) +kubectl apply -f deploy/k8s/pv.yaml + +# Apply the PersistentVolumeClaims (PVCs) +kubectl apply -f deploy/k8s/pvc.yaml +``` + +### Step 3: Configure the Application + +Before deploying the application, you need to edit the `deploy/k8s/configmap.yaml` file to modify sensitive information and custom settings. + +**It is strongly recommended to change the following fields:** +- `DJANGO_SECRET_KEY`: Change to a random, complex string. +- `DJANGO_MYSQL_PASSWORD` and `MYSQL_ROOT_PASSWORD`: Change to your own secure database password. + +```bash +# Edit the ConfigMap file +vim deploy/k8s/configmap.yaml + +# Apply the configuration +kubectl apply -f deploy/k8s/configmap.yaml +``` + +### Step 4: Deploy the Application Stack + +Now, we can deploy all the core services. + +```bash +# Deploy the Deployments (DjangoBlog, MySQL, Redis, Nginx, ES) +kubectl apply -f deploy/k8s/deployment.yaml + +# Deploy the Services (to create internal endpoints for the Deployments) +kubectl apply -f deploy/k8s/service.yaml +``` + +The deployment may take some time. You can run the following command to check if all Pods are running successfully (STATUS should be `Running`): + +```bash +kubectl get pods -n djangoblog -w +``` + +### Step 5: Expose the Application Externally + +Finally, expose the Nginx service to external traffic by applying the `Ingress` rule. + +```bash +# Apply the Ingress rule +kubectl apply -f deploy/k8s/gateway.yaml +``` + +Once deployed, you can access your blog via the external IP address of your Ingress Controller. Use the following command to find the address: + +```bash +kubectl get ingress -n djangoblog +``` + +### Step 6: First-Time Initialization + +Similar to the Docker deployment, you need to get a shell into the DjangoBlog application Pod to perform database initialization and create a superuser on the first run. + +```bash +# First, get the name of a djangoblog pod +kubectl get pods -n djangoblog | grep djangoblog + +# Exec into one of the Pods (replace [pod-name] with the name from the previous step) +kubectl exec -it [pod-name] -n djangoblog -- bash + +# Inside the Pod, run the following commands: +# Create a superuser account (follow the prompts) +python manage.py createsuperuser + +# (Optional) Create some test data +python manage.py create_testdata + +# (Optional, if ES is enabled) Create the search index +python manage.py rebuild_index + +# Exit the Pod +exit +``` + +Congratulations! You have successfully deployed DjangoBlog on your Kubernetes cluster. \ No newline at end of file diff --git a/docs/k8s.md b/docs/k8s.md new file mode 100644 index 0000000..9da3c28 --- /dev/null +++ b/docs/k8s.md @@ -0,0 +1,141 @@ +# 使用 Kubernetes 部署 DjangoBlog + +本文档将指导您如何在 Kubernetes (K8s) 集群上部署 DjangoBlog 应用。我们提供了一套完整的 `.yaml` 配置文件,位于 `deploy/k8s` 目录下,用于部署一个包含 DjangoBlog 应用、Nginx、MySQL、Redis 和 Elasticsearch 的完整服务栈。 + +## 架构概览 + +本次部署采用的是微服务化的云原生架构: + +- **核心组件**: 每个核心服务 (DjangoBlog, Nginx, MySQL, Redis, Elasticsearch) 都将作为独立的 `Deployment` 运行。 +- **配置管理**: Nginx 的配置文件和 Django 应用的环境变量通过 `ConfigMap` 进行管理。**注意:敏感信息(如密码)建议使用 `Secret` 进行管理。** +- **服务发现**: 所有服务都通过 `ClusterIP` 类型的 `Service` 在集群内部暴露,并通过服务名相互通信。 +- **外部访问**: 使用 `Ingress` 资源将外部的 HTTP 流量路由到 Nginx 服务,作为整个博客应用的统一入口。 +- **数据持久化**: 采用基于节点本地路径的 `local-storage` 方案。这需要您在指定的 K8s 节点上手动创建存储目录,并通过 `PersistentVolume` (PV) 和 `PersistentVolumeClaim` (PVC) 进行静态绑定。 + +## 1. 环境准备 + +在开始之前,请确保您已具备以下环境: + +- 一个正在运行的 Kubernetes 集群。 +- `kubectl` 命令行工具已配置并能够连接到您的集群。 +- 集群中已安装并配置好 [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/deploy/)。 +- 对集群中的一个节点(默认为 `master`)拥有文件系统访问权限,用于创建本地存储目录。 + +## 2. 部署步骤 + +### 步骤 1: 创建命名空间 + +我们建议将 DjangoBlog 相关的所有资源都部署在一个独立的命名空间中,便于管理。 + +```bash +# 创建一个名为 djangoblog 的命名空间 +kubectl create namespace djangoblog +``` + +### 步骤 2: 配置持久化存储 + +此方案使用本地持久卷 (Local Persistent Volume)。您需要在集群的一个节点上(在 `pv.yaml` 文件中默认为 `master` 节点)创建用于数据存储的目录。 + +```bash +# 登录到您的 master 节点 +ssh user@master-node + +# 创建所需的存储目录 +sudo mkdir -p /mnt/local-storage-db +sudo mkdir -p /mnt/local-storage-djangoblog +sudo mkdir -p /mnt/resource/ +sudo mkdir -p /mnt/local-storage-elasticsearch + +# 退出节点 +exit +``` +**注意**: 如果您希望将数据存储在其他节点或使用不同的路径,请务必修改 `deploy/k8s/pv.yaml` 文件中 `nodeAffinity` 和 `local.path` 的配置。 + +创建目录后,应用存储相关的配置文件: + +```bash +# 应用 StorageClass +kubectl apply -f deploy/k8s/storageclass.yaml + +# 应用 PersistentVolume (PV) +kubectl apply -f deploy/k8s/pv.yaml + +# 应用 PersistentVolumeClaim (PVC) +kubectl apply -f deploy/k8s/pvc.yaml +``` + +### 步骤 3: 配置应用 + +在部署应用之前,您需要编辑 `deploy/k8s/configmap.yaml` 文件,修改其中的敏感信息和个性化配置。 + +**强烈建议修改以下字段:** +- `DJANGO_SECRET_KEY`: 修改为一个随机且复杂的字符串。 +- `DJANGO_MYSQL_PASSWORD` 和 `MYSQL_ROOT_PASSWORD`: 修改为您自己的数据库密码。 + +```bash +# 编辑 ConfigMap 文件 +vim deploy/k8s/configmap.yaml + +# 应用配置 +kubectl apply -f deploy/k8s/configmap.yaml +``` + +### 步骤 4: 部署应用服务栈 + +现在,我们可以部署所有的核心服务了。 + +```bash +# 部署 Deployments (DjangoBlog, MySQL, Redis, Nginx, ES) +kubectl apply -f deploy/k8s/deployment.yaml + +# 部署 Services (为 Deployments 创建内部访问端点) +kubectl apply -f deploy/k8s/service.yaml +``` + +部署需要一些时间,您可以运行以下命令检查所有 Pod 是否都已成功运行 (STATUS 为 `Running`): + +```bash +kubectl get pods -n djangoblog -w +``` + +### 步骤 5: 暴露应用到外部 + +最后,通过应用 `Ingress` 规则来将外部流量引导至我们的 Nginx 服务。 + +```bash +# 应用 Ingress 规则 +kubectl apply -f deploy/k8s/gateway.yaml +``` + +部署完成后,您可以通过 Ingress Controller 的外部 IP 地址来访问您的博客。执行以下命令获取地址: + +```bash +kubectl get ingress -n djangoblog +``` + +### 步骤 6: 首次运行的初始化操作 + +与 Docker 部署类似,首次运行时,您需要进入 DjangoBlog 应用的 Pod 来执行数据库初始化和创建管理员账户。 + +```bash +# 首先,获取 djangoblog pod 的名称 +kubectl get pods -n djangoblog | grep djangoblog + +# 进入其中一个 Pod (将 [pod-name] 替换为上一步获取到的名称) +kubectl exec -it [pod-name] -n djangoblog -- bash + +# 在 Pod 内部执行以下命令: +# 创建超级管理员账户 (请按照提示操作) +python manage.py createsuperuser + +# (可选) 创建测试数据 +python manage.py create_testdata + +# (可选,如果启用了 ES) 创建索引 +python manage.py rebuild_index + +# 退出 Pod +exit +``` + +至此,您已成功在 Kubernetes 集群上完成了 DjangoBlog 的部署! \ No newline at end of file diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..f63669f46b3283a84e04098a7338b55f204e7b9d GIT binary patch literal 11097 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 literal 0 HcmV?d00001 diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..c80b30a --- /dev/null +++ b/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,685 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-13 16:02+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: .\accounts\admin.py:12 +msgid "password" +msgstr "password" + +#: .\accounts\admin.py:13 +msgid "Enter password again" +msgstr "Enter password again" + +#: .\accounts\admin.py:24 .\accounts\forms.py:89 +msgid "passwords do not match" +msgstr "passwords do not match" + +#: .\accounts\forms.py:36 +msgid "email already exists" +msgstr "email already exists" + +#: .\accounts\forms.py:46 .\accounts\forms.py:50 +msgid "New password" +msgstr "New password" + +#: .\accounts\forms.py:60 +msgid "Confirm password" +msgstr "Confirm password" + +#: .\accounts\forms.py:70 .\accounts\forms.py:116 +msgid "Email" +msgstr "Email" + +#: .\accounts\forms.py:76 .\accounts\forms.py:80 +msgid "Code" +msgstr "Code" + +#: .\accounts\forms.py:100 .\accounts\tests.py:194 +msgid "email does not exist" +msgstr "email does not exist" + +#: .\accounts\models.py:12 .\oauth\models.py:17 +msgid "nick name" +msgstr "nick name" + +#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266 +#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23 +#: .\oauth\models.py:53 +msgid "creation time" +msgstr "creation time" + +#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24 +#: .\oauth\models.py:54 +msgid "last modify time" +msgstr "last modify time" + +#: .\accounts\models.py:15 +msgid "create source" +msgstr "create source" + +#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:81 +msgid "user" +msgstr "user" + +#: .\accounts\tests.py:216 .\accounts\utils.py:39 +msgid "Verification code error" +msgstr "Verification code error" + +#: .\accounts\utils.py:13 +msgid "Verify Email" +msgstr "Verify Email" + +#: .\accounts\utils.py:21 +#, python-format +msgid "" +"You are resetting the password, the verification code is:%(code)s, valid " +"within 5 minutes, please keep it properly" +msgstr "" +"You are resetting the password, the verification code is:%(code)s, valid " +"within 5 minutes, please keep it properly" + +#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17 +#: .\oauth\models.py:12 +msgid "author" +msgstr "author" + +#: .\blog\admin.py:53 +msgid "Publish selected articles" +msgstr "Publish selected articles" + +#: .\blog\admin.py:54 +msgid "Draft selected articles" +msgstr "Draft selected articles" + +#: .\blog\admin.py:55 +msgid "Close article comments" +msgstr "Close article comments" + +#: .\blog\admin.py:56 +msgid "Open article comments" +msgstr "Open article comments" + +#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183 +#: .\templates\blog\tags\sidebar.html:40 +msgid "category" +msgstr "category" + +#: .\blog\models.py:20 .\blog\models.py:179 .\templates\share_layout\nav.html:8 +msgid "index" +msgstr "index" + +#: .\blog\models.py:21 +msgid "list" +msgstr "list" + +#: .\blog\models.py:22 +msgid "post" +msgstr "post" + +#: .\blog\models.py:23 +msgid "all" +msgstr "all" + +#: .\blog\models.py:24 +msgid "slide" +msgstr "slide" + +#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285 +msgid "modify time" +msgstr "modify time" + +#: .\blog\models.py:63 +msgid "Draft" +msgstr "Draft" + +#: .\blog\models.py:64 +msgid "Published" +msgstr "Published" + +#: .\blog\models.py:67 +msgid "Open" +msgstr "Open" + +#: .\blog\models.py:68 +msgid "Close" +msgstr "Close" + +#: .\blog\models.py:71 .\comments\admin.py:47 +msgid "Article" +msgstr "Article" + +#: .\blog\models.py:72 +msgid "Page" +msgstr "Page" + +#: .\blog\models.py:74 .\blog\models.py:280 +msgid "title" +msgstr "title" + +#: .\blog\models.py:75 +msgid "body" +msgstr "body" + +#: .\blog\models.py:77 +msgid "publish time" +msgstr "publish time" + +#: .\blog\models.py:79 +msgid "status" +msgstr "status" + +#: .\blog\models.py:84 +msgid "comment status" +msgstr "comment status" + +#: .\blog\models.py:88 .\oauth\models.py:43 +msgid "type" +msgstr "type" + +#: .\blog\models.py:89 +msgid "views" +msgstr "views" + +#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282 +msgid "order" +msgstr "order" + +#: .\blog\models.py:98 +msgid "show toc" +msgstr "show toc" + +#: .\blog\models.py:105 .\blog\models.py:249 +msgid "tag" +msgstr "tag" + +#: .\blog\models.py:115 .\comments\models.py:21 +msgid "article" +msgstr "article" + +#: .\blog\models.py:171 +msgid "category name" +msgstr "category name" + +#: .\blog\models.py:174 +msgid "parent category" +msgstr "parent category" + +#: .\blog\models.py:234 +msgid "tag name" +msgstr "tag name" + +#: .\blog\models.py:256 +msgid "link name" +msgstr "link name" + +#: .\blog\models.py:257 .\blog\models.py:271 +msgid "link" +msgstr "link" + +#: .\blog\models.py:260 +msgid "is show" +msgstr "is show" + +#: .\blog\models.py:262 +msgid "show type" +msgstr "show type" + +#: .\blog\models.py:281 +msgid "content" +msgstr "content" + +#: .\blog\models.py:283 .\oauth\models.py:52 +msgid "is enable" +msgstr "is enable" + +#: .\blog\models.py:289 +msgid "sidebar" +msgstr "sidebar" + +#: .\blog\models.py:299 +msgid "site name" +msgstr "site name" + +#: .\blog\models.py:305 +msgid "site description" +msgstr "site description" + +#: .\blog\models.py:311 +msgid "site seo description" +msgstr "site seo description" + +#: .\blog\models.py:313 +msgid "site keywords" +msgstr "site keywords" + +#: .\blog\models.py:318 +msgid "article sub length" +msgstr "article sub length" + +#: .\blog\models.py:319 +msgid "sidebar article count" +msgstr "sidebar article count" + +#: .\blog\models.py:320 +msgid "sidebar comment count" +msgstr "sidebar comment count" + +#: .\blog\models.py:321 +msgid "article comment count" +msgstr "article comment count" + +#: .\blog\models.py:322 +msgid "show adsense" +msgstr "show adsense" + +#: .\blog\models.py:324 +msgid "adsense code" +msgstr "adsense code" + +#: .\blog\models.py:325 +msgid "open site comment" +msgstr "open site comment" + +#: .\blog\models.py:352 +msgid "Website configuration" +msgstr "Website configuration" + +#: .\blog\models.py:360 +msgid "There can only be one configuration" +msgstr "There can only be one configuration" + +#: .\blog\views.py:348 +msgid "" +"Sorry, the page you requested is not found, please click the home page to " +"see other?" +msgstr "" +"Sorry, the page you requested is not found, please click the home page to " +"see other?" + +#: .\blog\views.py:356 +msgid "Sorry, the server is busy, please click the home page to see other?" +msgstr "Sorry, the server is busy, please click the home page to see other?" + +#: .\blog\views.py:369 +msgid "Sorry, you do not have permission to access this page?" +msgstr "Sorry, you do not have permission to access this page?" + +#: .\comments\admin.py:15 +msgid "Disable comments" +msgstr "Disable comments" + +#: .\comments\admin.py:16 +msgid "Enable comments" +msgstr "Enable comments" + +#: .\comments\admin.py:46 +msgid "User" +msgstr "User" + +#: .\comments\models.py:25 +msgid "parent comment" +msgstr "parent comment" + +#: .\comments\models.py:29 +msgid "enable" +msgstr "enable" + +#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30 +msgid "comment" +msgstr "comment" + +#: .\comments\utils.py:13 +msgid "Thanks for your comment" +msgstr "Thanks for your comment" + +#: .\comments\utils.py:15 +#, python-format +msgid "" +"

Thank you very much for your comments on this site

\n" +" You can visit
%(article_title)s\n" +" to review your comments,\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s" +msgstr "" +"

Thank you very much for your comments on this site

\n" +" You can visit %(article_title)s\n" +" to review your comments,\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s" + +#: .\comments\utils.py:26 +#, python-format +msgid "" +"Your comment on " +"%(article_title)s
has \n" +" received a reply.
%(comment_body)s\n" +"
\n" +" go check it out!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s\n" +" " +msgstr "" +"Your comment on " +"%(article_title)s
has \n" +" received a reply.
%(comment_body)s\n" +"
\n" +" go check it out!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s\n" +" " + +#: .\djangoblog\logentryadmin.py:63 +msgid "object" +msgstr "object" + +#: .\djangoblog\settings.py:140 +msgid "English" +msgstr "English" + +#: .\djangoblog\settings.py:141 +msgid "Simplified Chinese" +msgstr "Simplified Chinese" + +#: .\djangoblog\settings.py:142 +msgid "Traditional Chinese" +msgstr "Traditional Chinese" + +#: .\oauth\models.py:30 +msgid "oauth user" +msgstr "oauth user" + +#: .\oauth\models.py:37 +msgid "weibo" +msgstr "weibo" + +#: .\oauth\models.py:38 +msgid "google" +msgstr "google" + +#: .\oauth\models.py:48 +msgid "callback url" +msgstr "callback url" + +#: .\oauth\models.py:59 +msgid "already exists" +msgstr "already exists" + +#: .\oauth\views.py:154 +#, python-format +msgid "" +"\n" +"

Congratulations, you have successfully bound your email address. You " +"can use\n" +" %(oauthuser_type)s to directly log in to this website without a " +"password.

\n" +" You are welcome to continue to follow this site, the address is\n" +" %(site)s\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link to your " +"browser.\n" +" %(site)s\n" +" " +msgstr "" +"\n" +"

Congratulations, you have successfully bound your email address. You " +"can use\n" +" %(oauthuser_type)s to directly log in to this website without a " +"password.

\n" +" You are welcome to continue to follow this site, the address is\n" +" %(site)s\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link to your " +"browser.\n" +" %(site)s\n" +" " + +#: .\oauth\views.py:165 +msgid "Congratulations on your successful binding!" +msgstr "Congratulations on your successful binding!" + +#: .\oauth\views.py:217 +#, python-format +msgid "" +"\n" +"

Please click the link below to bind your email

\n" +"\n" +" %(url)s\n" +"\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link " +"to your browser.\n" +"
\n" +" %(url)s\n" +" " +msgstr "" +"\n" +"

Please click the link below to bind your email

\n" +"\n" +" %(url)s\n" +"\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link " +"to your browser.\n" +"
\n" +" %(url)s\n" +" " + +#: .\oauth\views.py:228 .\oauth\views.py:240 +msgid "Bind your email" +msgstr "Bind your email" + +#: .\oauth\views.py:242 +msgid "" +"Congratulations, the binding is just one step away. Please log in to your " +"email to check the email to complete the binding. Thank you." +msgstr "" +"Congratulations, the binding is just one step away. Please log in to your " +"email to check the email to complete the binding. Thank you." + +#: .\oauth\views.py:245 +msgid "Binding successful" +msgstr "Binding successful" + +#: .\oauth\views.py:247 +#, python-format +msgid "" +"Congratulations, you have successfully bound your email address. You can use " +"%(oauthuser_type)s to directly log in to this website without a password. " +"You are welcome to continue to follow this site." +msgstr "" +"Congratulations, you have successfully bound your email address. You can use " +"%(oauthuser_type)s to directly log in to this website without a password. " +"You are welcome to continue to follow this site." + +#: .\templates\account\forget_password.html:7 +msgid "forget the password" +msgstr "forget the password" + +#: .\templates\account\forget_password.html:18 +msgid "get verification code" +msgstr "get verification code" + +#: .\templates\account\forget_password.html:19 +msgid "submit" +msgstr "submit" + +#: .\templates\account\login.html:36 +msgid "Create Account" +msgstr "Create Account" + +#: .\templates\account\login.html:42 +#, fuzzy +#| msgid "forget the password" +msgid "Forget Password" +msgstr "forget the password" + +#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126 +msgid "login" +msgstr "login" + +#: .\templates\account\result.html:22 +msgid "back to the homepage" +msgstr "back to the homepage" + +#: .\templates\blog\article_archives.html:7 +#: .\templates\blog\article_archives.html:24 +msgid "article archive" +msgstr "article archive" + +#: .\templates\blog\article_archives.html:32 +msgid "year" +msgstr "year" + +#: .\templates\blog\article_archives.html:36 +msgid "month" +msgstr "month" + +#: .\templates\blog\tags\article_info.html:12 +msgid "pin to top" +msgstr "pin to top" + +#: .\templates\blog\tags\article_info.html:28 +msgid "comments" +msgstr "comments" + +#: .\templates\blog\tags\article_info.html:58 +msgid "toc" +msgstr "toc" + +#: .\templates\blog\tags\article_meta_info.html:6 +msgid "posted in" +msgstr "posted in" + +#: .\templates\blog\tags\article_meta_info.html:14 +msgid "and tagged" +msgstr "and tagged" + +#: .\templates\blog\tags\article_meta_info.html:25 +msgid "by " +msgstr "by" + +#: .\templates\blog\tags\article_meta_info.html:29 +#, python-format +msgid "" +"\n" +" title=\"View all articles published by " +"%(article.author.username)s\"\n" +" " +msgstr "" +"\n" +" title=\"View all articles published by " +"%(article.author.username)s\"\n" +" " + +#: .\templates\blog\tags\article_meta_info.html:44 +msgid "on" +msgstr "on" + +#: .\templates\blog\tags\article_meta_info.html:54 +msgid "edit" +msgstr "edit" + +#: .\templates\blog\tags\article_pagination.html:4 +msgid "article navigation" +msgstr "article navigation" + +#: .\templates\blog\tags\article_pagination.html:9 +msgid "earlier articles" +msgstr "earlier articles" + +#: .\templates\blog\tags\article_pagination.html:12 +msgid "newer articles" +msgstr "newer articles" + +#: .\templates\blog\tags\article_tag_list.html:5 +msgid "tags" +msgstr "tags" + +#: .\templates\blog\tags\sidebar.html:7 +msgid "search" +msgstr "search" + +#: .\templates\blog\tags\sidebar.html:50 +msgid "recent comments" +msgstr "recent comments" + +#: .\templates\blog\tags\sidebar.html:57 +msgid "published on" +msgstr "published on" + +#: .\templates\blog\tags\sidebar.html:65 +msgid "recent articles" +msgstr "recent articles" + +#: .\templates\blog\tags\sidebar.html:77 +msgid "bookmark" +msgstr "bookmark" + +#: .\templates\blog\tags\sidebar.html:96 +msgid "Tag Cloud" +msgstr "Tag Cloud" + +#: .\templates\blog\tags\sidebar.html:107 +msgid "Welcome to star or fork the source code of this site" +msgstr "Welcome to star or fork the source code of this site" + +#: .\templates\blog\tags\sidebar.html:118 +msgid "Function" +msgstr "Function" + +#: .\templates\blog\tags\sidebar.html:120 +msgid "management site" +msgstr "management site" + +#: .\templates\blog\tags\sidebar.html:122 +msgid "logout" +msgstr "logout" + +#: .\templates\blog\tags\sidebar.html:129 +msgid "Track record" +msgstr "Track record" + +#: .\templates\blog\tags\sidebar.html:135 +msgid "Click me to return to the top" +msgstr "Click me to return to the top" + +#: .\templates\oauth\oauth_applications.html:5 +#| msgid "login" +msgid "quick login" +msgstr "quick login" + +#: .\templates\share_layout\nav.html:26 +msgid "Article archive" +msgstr "Article archive" diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..a2d36e98a180a2d9f413841d0cfa0c5f85654f63 GIT binary patch literal 10321 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, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-13 16:02+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: .\accounts\admin.py:12 +msgid "password" +msgstr "密码" + +#: .\accounts\admin.py:13 +msgid "Enter password again" +msgstr "再次输入密码" + +#: .\accounts\admin.py:24 .\accounts\forms.py:89 +msgid "passwords do not match" +msgstr "密码不匹配" + +#: .\accounts\forms.py:36 +msgid "email already exists" +msgstr "邮箱已存在" + +#: .\accounts\forms.py:46 .\accounts\forms.py:50 +msgid "New password" +msgstr "新密码" + +#: .\accounts\forms.py:60 +msgid "Confirm password" +msgstr "确认密码" + +#: .\accounts\forms.py:70 .\accounts\forms.py:116 +msgid "Email" +msgstr "邮箱" + +#: .\accounts\forms.py:76 .\accounts\forms.py:80 +msgid "Code" +msgstr "验证码" + +#: .\accounts\forms.py:100 .\accounts\tests.py:194 +msgid "email does not exist" +msgstr "邮箱不存在" + +#: .\accounts\models.py:12 .\oauth\models.py:17 +msgid "nick name" +msgstr "昵称" + +#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266 +#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23 +#: .\oauth\models.py:53 +msgid "creation time" +msgstr "创建时间" + +#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24 +#: .\oauth\models.py:54 +msgid "last modify time" +msgstr "最后修改时间" + +#: .\accounts\models.py:15 +msgid "create source" +msgstr "来源" + +#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:81 +msgid "user" +msgstr "用户" + +#: .\accounts\tests.py:216 .\accounts\utils.py:39 +msgid "Verification code error" +msgstr "验证码错误" + +#: .\accounts\utils.py:13 +msgid "Verify Email" +msgstr "验证邮箱" + +#: .\accounts\utils.py:21 +#, python-format +msgid "" +"You are resetting the password, the verification code is:%(code)s, valid " +"within 5 minutes, please keep it properly" +msgstr "您正在重置密码,验证码为:%(code)s,5分钟内有效 请妥善保管." + +#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17 +#: .\oauth\models.py:12 +msgid "author" +msgstr "作者" + +#: .\blog\admin.py:53 +msgid "Publish selected articles" +msgstr "发布选中的文章" + +#: .\blog\admin.py:54 +msgid "Draft selected articles" +msgstr "选中文章设为草稿" + +#: .\blog\admin.py:55 +msgid "Close article comments" +msgstr "关闭文章评论" + +#: .\blog\admin.py:56 +msgid "Open article comments" +msgstr "打开文章评论" + +#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183 +#: .\templates\blog\tags\sidebar.html:40 +msgid "category" +msgstr "分类目录" + +#: .\blog\models.py:20 .\blog\models.py:179 .\templates\share_layout\nav.html:8 +msgid "index" +msgstr "首页" + +#: .\blog\models.py:21 +msgid "list" +msgstr "列表" + +#: .\blog\models.py:22 +msgid "post" +msgstr "文章" + +#: .\blog\models.py:23 +msgid "all" +msgstr "所有" + +#: .\blog\models.py:24 +msgid "slide" +msgstr "侧边栏" + +#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285 +msgid "modify time" +msgstr "修改时间" + +#: .\blog\models.py:63 +msgid "Draft" +msgstr "草稿" + +#: .\blog\models.py:64 +msgid "Published" +msgstr "发布" + +#: .\blog\models.py:67 +msgid "Open" +msgstr "打开" + +#: .\blog\models.py:68 +msgid "Close" +msgstr "关闭" + +#: .\blog\models.py:71 .\comments\admin.py:47 +msgid "Article" +msgstr "文章" + +#: .\blog\models.py:72 +msgid "Page" +msgstr "页面" + +#: .\blog\models.py:74 .\blog\models.py:280 +msgid "title" +msgstr "标题" + +#: .\blog\models.py:75 +msgid "body" +msgstr "内容" + +#: .\blog\models.py:77 +msgid "publish time" +msgstr "发布时间" + +#: .\blog\models.py:79 +msgid "status" +msgstr "状态" + +#: .\blog\models.py:84 +msgid "comment status" +msgstr "评论状态" + +#: .\blog\models.py:88 .\oauth\models.py:43 +msgid "type" +msgstr "类型" + +#: .\blog\models.py:89 +msgid "views" +msgstr "阅读量" + +#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282 +msgid "order" +msgstr "排序" + +#: .\blog\models.py:98 +msgid "show toc" +msgstr "显示目录" + +#: .\blog\models.py:105 .\blog\models.py:249 +msgid "tag" +msgstr "标签" + +#: .\blog\models.py:115 .\comments\models.py:21 +msgid "article" +msgstr "文章" + +#: .\blog\models.py:171 +msgid "category name" +msgstr "分类名" + +#: .\blog\models.py:174 +msgid "parent category" +msgstr "上级分类" + +#: .\blog\models.py:234 +msgid "tag name" +msgstr "标签名" + +#: .\blog\models.py:256 +msgid "link name" +msgstr "链接名" + +#: .\blog\models.py:257 .\blog\models.py:271 +msgid "link" +msgstr "链接" + +#: .\blog\models.py:260 +msgid "is show" +msgstr "是否显示" + +#: .\blog\models.py:262 +msgid "show type" +msgstr "显示类型" + +#: .\blog\models.py:281 +msgid "content" +msgstr "内容" + +#: .\blog\models.py:283 .\oauth\models.py:52 +msgid "is enable" +msgstr "是否启用" + +#: .\blog\models.py:289 +msgid "sidebar" +msgstr "侧边栏" + +#: .\blog\models.py:299 +msgid "site name" +msgstr "站点名称" + +#: .\blog\models.py:305 +msgid "site description" +msgstr "站点描述" + +#: .\blog\models.py:311 +msgid "site seo description" +msgstr "站点SEO描述" + +#: .\blog\models.py:313 +msgid "site keywords" +msgstr "关键字" + +#: .\blog\models.py:318 +msgid "article sub length" +msgstr "文章摘要长度" + +#: .\blog\models.py:319 +msgid "sidebar article count" +msgstr "侧边栏文章数目" + +#: .\blog\models.py:320 +msgid "sidebar comment count" +msgstr "侧边栏评论数目" + +#: .\blog\models.py:321 +msgid "article comment count" +msgstr "文章页面默认显示评论数目" + +#: .\blog\models.py:322 +msgid "show adsense" +msgstr "是否显示广告" + +#: .\blog\models.py:324 +msgid "adsense code" +msgstr "广告内容" + +#: .\blog\models.py:325 +msgid "open site comment" +msgstr "公共头部" + +#: .\blog\models.py:352 +msgid "Website configuration" +msgstr "网站配置" + +#: .\blog\models.py:360 +msgid "There can only be one configuration" +msgstr "只能有一个配置" + +#: .\blog\views.py:348 +msgid "" +"Sorry, the page you requested is not found, please click the home page to " +"see other?" +msgstr "抱歉,你所访问的页面找不到,请点击首页看看别的?" + +#: .\blog\views.py:356 +msgid "Sorry, the server is busy, please click the home page to see other?" +msgstr "抱歉,服务出错了,请点击首页看看别的?" + +#: .\blog\views.py:369 +msgid "Sorry, you do not have permission to access this page?" +msgstr "抱歉,你没用权限访问此页面。" + +#: .\comments\admin.py:15 +msgid "Disable comments" +msgstr "禁用评论" + +#: .\comments\admin.py:16 +msgid "Enable comments" +msgstr "启用评论" + +#: .\comments\admin.py:46 +msgid "User" +msgstr "用户" + +#: .\comments\models.py:25 +msgid "parent comment" +msgstr "上级评论" + +#: .\comments\models.py:29 +msgid "enable" +msgstr "启用" + +#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30 +msgid "comment" +msgstr "评论" + +#: .\comments\utils.py:13 +msgid "Thanks for your comment" +msgstr "感谢你的评论" + +#: .\comments\utils.py:15 +#, python-format +msgid "" +"

Thank you very much for your comments on this site

\n" +" You can visit %(article_title)s\n" +" to review your comments,\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s" +msgstr "" +"

非常感谢您对此网站的评论

\n" +" 您可以访问%(article_title)s\n" +"查看您的评论,\n" +"再次感谢您!\n" +"
\n" +" 如果上面的链接打不开,请复制此链接链接到您的浏览器。\n" +"%(article_url)s" + +#: .\comments\utils.py:26 +#, python-format +msgid "" +"Your comment on " +"%(article_title)s
has \n" +" received a reply.
%(comment_body)s\n" +"
\n" +" go check it out!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s\n" +" " +msgstr "" +"您对 %(article_title)s
" +"的评论有\n" +" 收到回复。
%(comment_body)s\n" +"
\n" +"快去看看吧!\n" +"
\n" +" 如果上面的链接打不开,请复制此链接链接到您的浏览器。\n" +" %(article_url)s\n" +" " + +#: .\djangoblog\logentryadmin.py:63 +msgid "object" +msgstr "对象" + +#: .\djangoblog\settings.py:140 +msgid "English" +msgstr "英文" + +#: .\djangoblog\settings.py:141 +msgid "Simplified Chinese" +msgstr "简体中文" + +#: .\djangoblog\settings.py:142 +msgid "Traditional Chinese" +msgstr "繁体中文" + +#: .\oauth\models.py:30 +msgid "oauth user" +msgstr "第三方用户" + +#: .\oauth\models.py:37 +msgid "weibo" +msgstr "微博" + +#: .\oauth\models.py:38 +msgid "google" +msgstr "谷歌" + +#: .\oauth\models.py:48 +msgid "callback url" +msgstr "回调地址" + +#: .\oauth\models.py:59 +msgid "already exists" +msgstr "已经存在" + +#: .\oauth\views.py:154 +#, python-format +msgid "" +"\n" +"

Congratulations, you have successfully bound your email address. You " +"can use\n" +" %(oauthuser_type)s to directly log in to this website without a " +"password.

\n" +" You are welcome to continue to follow this site, the address is\n" +" %(site)s\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link to your " +"browser.\n" +" %(site)s\n" +" " +msgstr "" +"\n" +"

恭喜你已经绑定成功 你可以使用\n" +" %(oauthuser_type)s 来免密登录本站

\n" +" 欢迎继续关注本站, 地址是\n" +" %(site)s\n" +" 再次感谢你\n" +"
\n" +" 如果上面链接无法打开,请复制此链接到你的浏览器 \n" +" %(site)s\n" +" " + +#: .\oauth\views.py:165 +msgid "Congratulations on your successful binding!" +msgstr "恭喜你绑定成功" + +#: .\oauth\views.py:217 +#, python-format +msgid "" +"\n" +"

Please click the link below to bind your email

\n" +"\n" +" %(url)s\n" +"\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link " +"to your browser.\n" +"
\n" +" %(url)s\n" +" " +msgstr "" +"\n" +"

请点击下面的链接绑定您的邮箱

\n" +"\n" +" %(url)s\n" +"\n" +"再次感谢您!\n" +"
\n" +"如果上面的链接打不开,请复制此链接到您的浏览器。\n" +"%(url)s\n" +" " + +#: .\oauth\views.py:228 .\oauth\views.py:240 +msgid "Bind your email" +msgstr "绑定邮箱" + +#: .\oauth\views.py:242 +msgid "" +"Congratulations, the binding is just one step away. Please log in to your " +"email to check the email to complete the binding. Thank you." +msgstr "恭喜您,还差一步就绑定成功了,请登录您的邮箱查看邮件完成绑定,谢谢。" + +#: .\oauth\views.py:245 +msgid "Binding successful" +msgstr "绑定成功" + +#: .\oauth\views.py:247 +#, python-format +msgid "" +"Congratulations, you have successfully bound your email address. You can use " +"%(oauthuser_type)s to directly log in to this website without a password. " +"You are welcome to continue to follow this site." +msgstr "" +"恭喜您绑定成功,您以后可以使用%(oauthuser_type)s来直接免密码登录本站啦,感谢" +"您对本站对关注。" + +#: .\templates\account\forget_password.html:7 +msgid "forget the password" +msgstr "忘记密码" + +#: .\templates\account\forget_password.html:18 +msgid "get verification code" +msgstr "获取验证码" + +#: .\templates\account\forget_password.html:19 +msgid "submit" +msgstr "提交" + +#: .\templates\account\login.html:36 +msgid "Create Account" +msgstr "创建账号" + +#: .\templates\account\login.html:42 +#| msgid "forget the password" +msgid "Forget Password" +msgstr "忘记密码" + +#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126 +msgid "login" +msgstr "登录" + +#: .\templates\account\result.html:22 +msgid "back to the homepage" +msgstr "返回首页吧" + +#: .\templates\blog\article_archives.html:7 +#: .\templates\blog\article_archives.html:24 +msgid "article archive" +msgstr "文章归档" + +#: .\templates\blog\article_archives.html:32 +msgid "year" +msgstr "年" + +#: .\templates\blog\article_archives.html:36 +msgid "month" +msgstr "月" + +#: .\templates\blog\tags\article_info.html:12 +msgid "pin to top" +msgstr "置顶" + +#: .\templates\blog\tags\article_info.html:28 +msgid "comments" +msgstr "评论" + +#: .\templates\blog\tags\article_info.html:58 +msgid "toc" +msgstr "目录" + +#: .\templates\blog\tags\article_meta_info.html:6 +msgid "posted in" +msgstr "发布于" + +#: .\templates\blog\tags\article_meta_info.html:14 +msgid "and tagged" +msgstr "并标记为" + +#: .\templates\blog\tags\article_meta_info.html:25 +msgid "by " +msgstr "由" + +#: .\templates\blog\tags\article_meta_info.html:29 +#, python-format +msgid "" +"\n" +" title=\"View all articles published by " +"%(article.author.username)s\"\n" +" " +msgstr "" +"\n" +" title=\"查看所有由 %(article.author.username)s\"发布的文章\n" +" " + +#: .\templates\blog\tags\article_meta_info.html:44 +msgid "on" +msgstr "在" + +#: .\templates\blog\tags\article_meta_info.html:54 +msgid "edit" +msgstr "编辑" + +#: .\templates\blog\tags\article_pagination.html:4 +msgid "article navigation" +msgstr "文章导航" + +#: .\templates\blog\tags\article_pagination.html:9 +msgid "earlier articles" +msgstr "早期文章" + +#: .\templates\blog\tags\article_pagination.html:12 +msgid "newer articles" +msgstr "较新文章" + +#: .\templates\blog\tags\article_tag_list.html:5 +msgid "tags" +msgstr "标签" + +#: .\templates\blog\tags\sidebar.html:7 +msgid "search" +msgstr "搜索" + +#: .\templates\blog\tags\sidebar.html:50 +msgid "recent comments" +msgstr "近期评论" + +#: .\templates\blog\tags\sidebar.html:57 +msgid "published on" +msgstr "发表于" + +#: .\templates\blog\tags\sidebar.html:65 +msgid "recent articles" +msgstr "近期文章" + +#: .\templates\blog\tags\sidebar.html:77 +msgid "bookmark" +msgstr "书签" + +#: .\templates\blog\tags\sidebar.html:96 +msgid "Tag Cloud" +msgstr "标签云" + +#: .\templates\blog\tags\sidebar.html:107 +msgid "Welcome to star or fork the source code of this site" +msgstr "欢迎您STAR或者FORK本站源代码" + +#: .\templates\blog\tags\sidebar.html:118 +msgid "Function" +msgstr "功能" + +#: .\templates\blog\tags\sidebar.html:120 +msgid "management site" +msgstr "管理站点" + +#: .\templates\blog\tags\sidebar.html:122 +msgid "logout" +msgstr "登出" + +#: .\templates\blog\tags\sidebar.html:129 +msgid "Track record" +msgstr "运动轨迹记录" + +#: .\templates\blog\tags\sidebar.html:135 +msgid "Click me to return to the top" +msgstr "点我返回顶部" + +#: .\templates\oauth\oauth_applications.html:5 +#| msgid "login" +msgid "quick login" +msgstr "快捷登录" + +#: .\templates\share_layout\nav.html:26 +msgid "Article archive" +msgstr "文章归档" diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..fe2ea17dc2636742b9c3b8d4eddb6293ee3b7290 GIT binary patch literal 10268 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 literal 0 HcmV?d00001 diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po new file mode 100644 index 0000000..a2920ce --- /dev/null +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -0,0 +1,668 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-13 16:02+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: .\accounts\admin.py:12 +msgid "password" +msgstr "密碼" + +#: .\accounts\admin.py:13 +msgid "Enter password again" +msgstr "再次輸入密碼" + +#: .\accounts\admin.py:24 .\accounts\forms.py:89 +msgid "passwords do not match" +msgstr "密碼不匹配" + +#: .\accounts\forms.py:36 +msgid "email already exists" +msgstr "郵箱已存在" + +#: .\accounts\forms.py:46 .\accounts\forms.py:50 +msgid "New password" +msgstr "新密碼" + +#: .\accounts\forms.py:60 +msgid "Confirm password" +msgstr "確認密碼" + +#: .\accounts\forms.py:70 .\accounts\forms.py:116 +msgid "Email" +msgstr "郵箱" + +#: .\accounts\forms.py:76 .\accounts\forms.py:80 +msgid "Code" +msgstr "驗證碼" + +#: .\accounts\forms.py:100 .\accounts\tests.py:194 +msgid "email does not exist" +msgstr "郵箱不存在" + +#: .\accounts\models.py:12 .\oauth\models.py:17 +msgid "nick name" +msgstr "昵稱" + +#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266 +#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23 +#: .\oauth\models.py:53 +msgid "creation time" +msgstr "創建時間" + +#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24 +#: .\oauth\models.py:54 +msgid "last modify time" +msgstr "最後修改時間" + +#: .\accounts\models.py:15 +msgid "create source" +msgstr "來源" + +#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:81 +msgid "user" +msgstr "用戶" + +#: .\accounts\tests.py:216 .\accounts\utils.py:39 +msgid "Verification code error" +msgstr "驗證碼錯誤" + +#: .\accounts\utils.py:13 +msgid "Verify Email" +msgstr "驗證郵箱" + +#: .\accounts\utils.py:21 +#, python-format +msgid "" +"You are resetting the password, the verification code is:%(code)s, valid " +"within 5 minutes, please keep it properly" +msgstr "您正在重置密碼,驗證碼為:%(code)s,5分鐘內有效 請妥善保管." + +#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17 +#: .\oauth\models.py:12 +msgid "author" +msgstr "作者" + +#: .\blog\admin.py:53 +msgid "Publish selected articles" +msgstr "發布選中的文章" + +#: .\blog\admin.py:54 +msgid "Draft selected articles" +msgstr "選中文章設為草稿" + +#: .\blog\admin.py:55 +msgid "Close article comments" +msgstr "關閉文章評論" + +#: .\blog\admin.py:56 +msgid "Open article comments" +msgstr "打開文章評論" + +#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183 +#: .\templates\blog\tags\sidebar.html:40 +msgid "category" +msgstr "分類目錄" + +#: .\blog\models.py:20 .\blog\models.py:179 .\templates\share_layout\nav.html:8 +msgid "index" +msgstr "首頁" + +#: .\blog\models.py:21 +msgid "list" +msgstr "列表" + +#: .\blog\models.py:22 +msgid "post" +msgstr "文章" + +#: .\blog\models.py:23 +msgid "all" +msgstr "所有" + +#: .\blog\models.py:24 +msgid "slide" +msgstr "側邊欄" + +#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285 +msgid "modify time" +msgstr "修改時間" + +#: .\blog\models.py:63 +msgid "Draft" +msgstr "草稿" + +#: .\blog\models.py:64 +msgid "Published" +msgstr "發布" + +#: .\blog\models.py:67 +msgid "Open" +msgstr "打開" + +#: .\blog\models.py:68 +msgid "Close" +msgstr "關閉" + +#: .\blog\models.py:71 .\comments\admin.py:47 +msgid "Article" +msgstr "文章" + +#: .\blog\models.py:72 +msgid "Page" +msgstr "頁面" + +#: .\blog\models.py:74 .\blog\models.py:280 +msgid "title" +msgstr "標題" + +#: .\blog\models.py:75 +msgid "body" +msgstr "內容" + +#: .\blog\models.py:77 +msgid "publish time" +msgstr "發布時間" + +#: .\blog\models.py:79 +msgid "status" +msgstr "狀態" + +#: .\blog\models.py:84 +msgid "comment status" +msgstr "評論狀態" + +#: .\blog\models.py:88 .\oauth\models.py:43 +msgid "type" +msgstr "類型" + +#: .\blog\models.py:89 +msgid "views" +msgstr "閱讀量" + +#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282 +msgid "order" +msgstr "排序" + +#: .\blog\models.py:98 +msgid "show toc" +msgstr "顯示目錄" + +#: .\blog\models.py:105 .\blog\models.py:249 +msgid "tag" +msgstr "標簽" + +#: .\blog\models.py:115 .\comments\models.py:21 +msgid "article" +msgstr "文章" + +#: .\blog\models.py:171 +msgid "category name" +msgstr "分類名" + +#: .\blog\models.py:174 +msgid "parent category" +msgstr "上級分類" + +#: .\blog\models.py:234 +msgid "tag name" +msgstr "標簽名" + +#: .\blog\models.py:256 +msgid "link name" +msgstr "鏈接名" + +#: .\blog\models.py:257 .\blog\models.py:271 +msgid "link" +msgstr "鏈接" + +#: .\blog\models.py:260 +msgid "is show" +msgstr "是否顯示" + +#: .\blog\models.py:262 +msgid "show type" +msgstr "顯示類型" + +#: .\blog\models.py:281 +msgid "content" +msgstr "內容" + +#: .\blog\models.py:283 .\oauth\models.py:52 +msgid "is enable" +msgstr "是否啟用" + +#: .\blog\models.py:289 +msgid "sidebar" +msgstr "側邊欄" + +#: .\blog\models.py:299 +msgid "site name" +msgstr "站點名稱" + +#: .\blog\models.py:305 +msgid "site description" +msgstr "站點描述" + +#: .\blog\models.py:311 +msgid "site seo description" +msgstr "站點SEO描述" + +#: .\blog\models.py:313 +msgid "site keywords" +msgstr "關鍵字" + +#: .\blog\models.py:318 +msgid "article sub length" +msgstr "文章摘要長度" + +#: .\blog\models.py:319 +msgid "sidebar article count" +msgstr "側邊欄文章數目" + +#: .\blog\models.py:320 +msgid "sidebar comment count" +msgstr "側邊欄評論數目" + +#: .\blog\models.py:321 +msgid "article comment count" +msgstr "文章頁面默認顯示評論數目" + +#: .\blog\models.py:322 +msgid "show adsense" +msgstr "是否顯示廣告" + +#: .\blog\models.py:324 +msgid "adsense code" +msgstr "廣告內容" + +#: .\blog\models.py:325 +msgid "open site comment" +msgstr "公共頭部" + +#: .\blog\models.py:352 +msgid "Website configuration" +msgstr "網站配置" + +#: .\blog\models.py:360 +msgid "There can only be one configuration" +msgstr "只能有一個配置" + +#: .\blog\views.py:348 +msgid "" +"Sorry, the page you requested is not found, please click the home page to " +"see other?" +msgstr "抱歉,你所訪問的頁面找不到,請點擊首頁看看別的?" + +#: .\blog\views.py:356 +msgid "Sorry, the server is busy, please click the home page to see other?" +msgstr "抱歉,服務出錯了,請點擊首頁看看別的?" + +#: .\blog\views.py:369 +msgid "Sorry, you do not have permission to access this page?" +msgstr "抱歉,你沒用權限訪問此頁面。" + +#: .\comments\admin.py:15 +msgid "Disable comments" +msgstr "禁用評論" + +#: .\comments\admin.py:16 +msgid "Enable comments" +msgstr "啟用評論" + +#: .\comments\admin.py:46 +msgid "User" +msgstr "用戶" + +#: .\comments\models.py:25 +msgid "parent comment" +msgstr "上級評論" + +#: .\comments\models.py:29 +msgid "enable" +msgstr "啟用" + +#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30 +msgid "comment" +msgstr "評論" + +#: .\comments\utils.py:13 +msgid "Thanks for your comment" +msgstr "感謝你的評論" + +#: .\comments\utils.py:15 +#, python-format +msgid "" +"

Thank you very much for your comments on this site

\n" +" You can visit %(article_title)s\n" +" to review your comments,\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s" +msgstr "" +"

非常感謝您對此網站的評論

\n" +" 您可以訪問%(article_title)s\n" +"查看您的評論,\n" +"再次感謝您!\n" +"
\n" +" 如果上面的鏈接打不開,請復製此鏈接鏈接到您的瀏覽器。\n" +"%(article_url)s" + +#: .\comments\utils.py:26 +#, python-format +msgid "" +"Your comment on " +"%(article_title)s
has \n" +" received a reply.
%(comment_body)s\n" +"
\n" +" go check it out!\n" +"
\n" +" If the link above cannot be opened, please copy this " +"link to your browser.\n" +" %(article_url)s\n" +" " +msgstr "" +"您對 %(article_title)s
" +"的評論有\n" +" 收到回復。
%(comment_body)s\n" +"
\n" +"快去看看吧!\n" +"
\n" +" 如果上面的鏈接打不開,請復製此鏈接鏈接到您的瀏覽器。\n" +" %(article_url)s\n" +" " + +#: .\djangoblog\logentryadmin.py:63 +msgid "object" +msgstr "對象" + +#: .\djangoblog\settings.py:140 +msgid "English" +msgstr "英文" + +#: .\djangoblog\settings.py:141 +msgid "Simplified Chinese" +msgstr "簡體中文" + +#: .\djangoblog\settings.py:142 +msgid "Traditional Chinese" +msgstr "繁體中文" + +#: .\oauth\models.py:30 +msgid "oauth user" +msgstr "第三方用戶" + +#: .\oauth\models.py:37 +msgid "weibo" +msgstr "微博" + +#: .\oauth\models.py:38 +msgid "google" +msgstr "谷歌" + +#: .\oauth\models.py:48 +msgid "callback url" +msgstr "回調地址" + +#: .\oauth\models.py:59 +msgid "already exists" +msgstr "已經存在" + +#: .\oauth\views.py:154 +#, python-format +msgid "" +"\n" +"

Congratulations, you have successfully bound your email address. You " +"can use\n" +" %(oauthuser_type)s to directly log in to this website without a " +"password.

\n" +" You are welcome to continue to follow this site, the address is\n" +" %(site)s\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link to your " +"browser.\n" +" %(site)s\n" +" " +msgstr "" +"\n" +"

恭喜你已經綁定成功 你可以使用\n" +" %(oauthuser_type)s 來免密登錄本站

\n" +" 歡迎繼續關註本站, 地址是\n" +" %(site)s\n" +" 再次感謝你\n" +"
\n" +" 如果上面鏈接無法打開,請復製此鏈接到你的瀏覽器 \n" +" %(site)s\n" +" " + +#: .\oauth\views.py:165 +msgid "Congratulations on your successful binding!" +msgstr "恭喜你綁定成功" + +#: .\oauth\views.py:217 +#, python-format +msgid "" +"\n" +"

Please click the link below to bind your email

\n" +"\n" +" %(url)s\n" +"\n" +" Thank you again!\n" +"
\n" +" If the link above cannot be opened, please copy this link " +"to your browser.\n" +"
\n" +" %(url)s\n" +" " +msgstr "" +"\n" +"

請點擊下面的鏈接綁定您的郵箱

\n" +"\n" +" %(url)s\n" +"\n" +"再次感謝您!\n" +"
\n" +"如果上面的鏈接打不開,請復製此鏈接到您的瀏覽器。\n" +"%(url)s\n" +" " + +#: .\oauth\views.py:228 .\oauth\views.py:240 +msgid "Bind your email" +msgstr "綁定郵箱" + +#: .\oauth\views.py:242 +msgid "" +"Congratulations, the binding is just one step away. Please log in to your " +"email to check the email to complete the binding. Thank you." +msgstr "恭喜您,還差一步就綁定成功了,請登錄您的郵箱查看郵件完成綁定,謝謝。" + +#: .\oauth\views.py:245 +msgid "Binding successful" +msgstr "綁定成功" + +#: .\oauth\views.py:247 +#, python-format +msgid "" +"Congratulations, you have successfully bound your email address. You can use " +"%(oauthuser_type)s to directly log in to this website without a password. " +"You are welcome to continue to follow this site." +msgstr "" +"恭喜您綁定成功,您以後可以使用%(oauthuser_type)s來直接免密碼登錄本站啦,感謝" +"您對本站對關註。" + +#: .\templates\account\forget_password.html:7 +msgid "forget the password" +msgstr "忘記密碼" + +#: .\templates\account\forget_password.html:18 +msgid "get verification code" +msgstr "獲取驗證碼" + +#: .\templates\account\forget_password.html:19 +msgid "submit" +msgstr "提交" + +#: .\templates\account\login.html:36 +msgid "Create Account" +msgstr "創建賬號" + +#: .\templates\account\login.html:42 +#, fuzzy +#| msgid "forget the password" +msgid "Forget Password" +msgstr "忘記密碼" + +#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126 +msgid "login" +msgstr "登錄" + +#: .\templates\account\result.html:22 +msgid "back to the homepage" +msgstr "返回首頁吧" + +#: .\templates\blog\article_archives.html:7 +#: .\templates\blog\article_archives.html:24 +msgid "article archive" +msgstr "文章歸檔" + +#: .\templates\blog\article_archives.html:32 +msgid "year" +msgstr "年" + +#: .\templates\blog\article_archives.html:36 +msgid "month" +msgstr "月" + +#: .\templates\blog\tags\article_info.html:12 +msgid "pin to top" +msgstr "置頂" + +#: .\templates\blog\tags\article_info.html:28 +msgid "comments" +msgstr "評論" + +#: .\templates\blog\tags\article_info.html:58 +msgid "toc" +msgstr "目錄" + +#: .\templates\blog\tags\article_meta_info.html:6 +msgid "posted in" +msgstr "發布於" + +#: .\templates\blog\tags\article_meta_info.html:14 +msgid "and tagged" +msgstr "並標記為" + +#: .\templates\blog\tags\article_meta_info.html:25 +msgid "by " +msgstr "由" + +#: .\templates\blog\tags\article_meta_info.html:29 +#, python-format +msgid "" +"\n" +" title=\"View all articles published by " +"%(article.author.username)s\"\n" +" " +msgstr "" +"\n" +" title=\"查看所有由 %(article.author.username)s\"發布的文章\n" +" " + +#: .\templates\blog\tags\article_meta_info.html:44 +msgid "on" +msgstr "在" + +#: .\templates\blog\tags\article_meta_info.html:54 +msgid "edit" +msgstr "編輯" + +#: .\templates\blog\tags\article_pagination.html:4 +msgid "article navigation" +msgstr "文章導航" + +#: .\templates\blog\tags\article_pagination.html:9 +msgid "earlier articles" +msgstr "早期文章" + +#: .\templates\blog\tags\article_pagination.html:12 +msgid "newer articles" +msgstr "較新文章" + +#: .\templates\blog\tags\article_tag_list.html:5 +msgid "tags" +msgstr "標簽" + +#: .\templates\blog\tags\sidebar.html:7 +msgid "search" +msgstr "搜索" + +#: .\templates\blog\tags\sidebar.html:50 +msgid "recent comments" +msgstr "近期評論" + +#: .\templates\blog\tags\sidebar.html:57 +msgid "published on" +msgstr "發表於" + +#: .\templates\blog\tags\sidebar.html:65 +msgid "recent articles" +msgstr "近期文章" + +#: .\templates\blog\tags\sidebar.html:77 +msgid "bookmark" +msgstr "書簽" + +#: .\templates\blog\tags\sidebar.html:96 +msgid "Tag Cloud" +msgstr "標簽雲" + +#: .\templates\blog\tags\sidebar.html:107 +msgid "Welcome to star or fork the source code of this site" +msgstr "歡迎您STAR或者FORK本站源代碼" + +#: .\templates\blog\tags\sidebar.html:118 +msgid "Function" +msgstr "功能" + +#: .\templates\blog\tags\sidebar.html:120 +msgid "management site" +msgstr "管理站點" + +#: .\templates\blog\tags\sidebar.html:122 +msgid "logout" +msgstr "登出" + +#: .\templates\blog\tags\sidebar.html:129 +msgid "Track record" +msgstr "運動軌跡記錄" + +#: .\templates\blog\tags\sidebar.html:135 +msgid "Click me to return to the top" +msgstr "點我返回頂部" + +#: .\templates\oauth\oauth_applications.html:5 +#| msgid "login" +msgid "quick login" +msgstr "快捷登錄" + +#: .\templates\share_layout\nav.html:26 +msgid "Article archive" +msgstr "文章歸檔" diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..919ba74 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoblog.settings") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) diff --git a/oauth/__init__.py b/oauth/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oauth/admin.py b/oauth/admin.py new file mode 100644 index 0000000..57eab5f --- /dev/null +++ b/oauth/admin.py @@ -0,0 +1,54 @@ +import logging + +from django.contrib import admin +# Register your models here. +from django.urls import reverse +from django.utils.html import format_html + +logger = logging.getLogger(__name__) + + +class OAuthUserAdmin(admin.ModelAdmin): + search_fields = ('nickname', 'email') + list_per_page = 20 + list_display = ( + 'id', + 'nickname', + 'link_to_usermodel', + 'show_user_image', + 'type', + 'email', + ) + list_display_links = ('id', 'nickname') + 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] + + def has_add_permission(self, request): + return False + + def link_to_usermodel(self, obj): + if obj.author: + 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)) + + def show_user_image(self, obj): + img = obj.picture + return format_html( + u'' % + (img)) + + link_to_usermodel.short_description = '用户' + show_user_image.short_description = '用户头像' + + +class OAuthConfigAdmin(admin.ModelAdmin): + list_display = ('type', 'appkey', 'appsecret', 'is_enable') + list_filter = ('type',) diff --git a/oauth/apps.py b/oauth/apps.py new file mode 100644 index 0000000..17fcea2 --- /dev/null +++ b/oauth/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class OauthConfig(AppConfig): + name = 'oauth' diff --git a/oauth/forms.py b/oauth/forms.py new file mode 100644 index 0000000..0e4ede3 --- /dev/null +++ b/oauth/forms.py @@ -0,0 +1,12 @@ +from django.contrib.auth.forms import forms +from django.forms import widgets + + +class RequireEmailForm(forms.Form): + email = forms.EmailField(label='电子邮箱', required=True) + oauthid = forms.IntegerField(widget=forms.HiddenInput, required=False) + + def __init__(self, *args, **kwargs): + super(RequireEmailForm, self).__init__(*args, **kwargs) + self.fields['email'].widget = widgets.EmailInput( + attrs={'placeholder': "email", "class": "form-control"}) diff --git a/oauth/migrations/0001_initial.py b/oauth/migrations/0001_initial.py new file mode 100644 index 0000000..3aa3e03 --- /dev/null +++ b/oauth/migrations/0001_initial.py @@ -0,0 +1,57 @@ +# Generated by Django 4.1.7 on 2023-03-07 09:53 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='OAuthConfig', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('weibo', '微博'), ('google', '谷歌'), ('github', 'GitHub'), ('facebook', 'FaceBook'), ('qq', 'QQ')], default='a', max_length=10, verbose_name='类型')), + ('appkey', models.CharField(max_length=200, verbose_name='AppKey')), + ('appsecret', models.CharField(max_length=200, verbose_name='AppSecret')), + ('callback_url', models.CharField(default='http://www.baidu.com', max_length=200, verbose_name='回调地址')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': 'oauth配置', + 'verbose_name_plural': 'oauth配置', + 'ordering': ['-created_time'], + }, + ), + migrations.CreateModel( + name='OAuthUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('openid', models.CharField(max_length=50)), + ('nickname', models.CharField(max_length=50, verbose_name='昵称')), + ('token', models.CharField(blank=True, max_length=150, null=True)), + ('picture', models.CharField(blank=True, max_length=350, null=True)), + ('type', models.CharField(max_length=50)), + ('email', models.CharField(blank=True, max_length=50, null=True)), + ('metadata', models.TextField(blank=True, null=True)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')), + ], + options={ + 'verbose_name': 'oauth用户', + 'verbose_name_plural': 'oauth用户', + 'ordering': ['-created_time'], + }, + ), + ] diff --git a/oauth/migrations/0002_alter_oauthconfig_options_alter_oauthuser_options_and_more.py b/oauth/migrations/0002_alter_oauthconfig_options_alter_oauthuser_options_and_more.py new file mode 100644 index 0000000..d5cc70e --- /dev/null +++ b/oauth/migrations/0002_alter_oauthconfig_options_alter_oauthuser_options_and_more.py @@ -0,0 +1,86 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:13 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('oauth', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='oauthconfig', + options={'ordering': ['-creation_time'], 'verbose_name': 'oauth配置', 'verbose_name_plural': 'oauth配置'}, + ), + migrations.AlterModelOptions( + name='oauthuser', + options={'ordering': ['-creation_time'], 'verbose_name': 'oauth user', 'verbose_name_plural': 'oauth user'}, + ), + migrations.RemoveField( + model_name='oauthconfig', + name='created_time', + ), + migrations.RemoveField( + model_name='oauthconfig', + name='last_mod_time', + ), + migrations.RemoveField( + model_name='oauthuser', + name='created_time', + ), + migrations.RemoveField( + model_name='oauthuser', + name='last_mod_time', + ), + migrations.AddField( + model_name='oauthconfig', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='oauthconfig', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'), + ), + migrations.AddField( + model_name='oauthuser', + name='creation_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), + ), + migrations.AddField( + model_name='oauthuser', + name='last_modify_time', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'), + ), + migrations.AlterField( + model_name='oauthconfig', + name='callback_url', + field=models.CharField(default='', max_length=200, verbose_name='callback url'), + ), + migrations.AlterField( + model_name='oauthconfig', + name='is_enable', + field=models.BooleanField(default=True, verbose_name='is enable'), + ), + migrations.AlterField( + model_name='oauthconfig', + name='type', + field=models.CharField(choices=[('weibo', 'weibo'), ('google', 'google'), ('github', 'GitHub'), ('facebook', 'FaceBook'), ('qq', 'QQ')], default='a', max_length=10, verbose_name='type'), + ), + migrations.AlterField( + model_name='oauthuser', + name='author', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'), + ), + migrations.AlterField( + model_name='oauthuser', + name='nickname', + field=models.CharField(max_length=50, verbose_name='nickname'), + ), + ] diff --git a/oauth/migrations/0003_alter_oauthuser_nickname.py b/oauth/migrations/0003_alter_oauthuser_nickname.py new file mode 100644 index 0000000..6af08eb --- /dev/null +++ b/oauth/migrations/0003_alter_oauthuser_nickname.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-26 02:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('oauth', '0002_alter_oauthconfig_options_alter_oauthuser_options_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='oauthuser', + name='nickname', + field=models.CharField(max_length=50, verbose_name='nick name'), + ), + ] diff --git a/oauth/migrations/__init__.py b/oauth/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oauth/models.py b/oauth/models.py new file mode 100644 index 0000000..be838ed --- /dev/null +++ b/oauth/models.py @@ -0,0 +1,67 @@ +# Create your models here. +from django.conf import settings +from django.core.exceptions import ValidationError +from django.db import models +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ + + +class OAuthUser(models.Model): + author = models.ForeignKey( + settings.AUTH_USER_MODEL, + verbose_name=_('author'), + blank=True, + null=True, + on_delete=models.CASCADE) + openid = models.CharField(max_length=50) + nickname = models.CharField(max_length=50, verbose_name=_('nick name')) + token = models.CharField(max_length=150, null=True, blank=True) + picture = models.CharField(max_length=350, blank=True, null=True) + type = models.CharField(blank=False, null=False, max_length=50) + email = models.CharField(max_length=50, null=True, blank=True) + metadata = models.TextField(null=True, blank=True) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_modify_time = models.DateTimeField(_('last modify time'), default=now) + + def __str__(self): + return self.nickname + + class Meta: + verbose_name = _('oauth user') + verbose_name_plural = verbose_name + ordering = ['-creation_time'] + + +class OAuthConfig(models.Model): + TYPE = ( + ('weibo', _('weibo')), + ('google', _('google')), + ('github', 'GitHub'), + ('facebook', 'FaceBook'), + ('qq', 'QQ'), + ) + type = models.CharField(_('type'), 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=_('callback url'), + blank=False, + default='') + is_enable = models.BooleanField( + _('is enable'), default=True, blank=False, null=False) + creation_time = models.DateTimeField(_('creation time'), default=now) + last_modify_time = models.DateTimeField(_('last modify time'), default=now) + + def clean(self): + if OAuthConfig.objects.filter( + type=self.type).exclude(id=self.id).count(): + raise ValidationError(_(self.type + _('already exists'))) + + def __str__(self): + return self.type + + class Meta: + verbose_name = 'oauth配置' + verbose_name_plural = verbose_name + ordering = ['-creation_time'] diff --git a/oauth/oauthmanager.py b/oauth/oauthmanager.py new file mode 100644 index 0000000..2e7ceef --- /dev/null +++ b/oauth/oauthmanager.py @@ -0,0 +1,504 @@ +import json +import logging +import os +import urllib.parse +from abc import ABCMeta, abstractmethod + +import requests + +from djangoblog.utils import cache_decorator +from oauth.models import OAuthUser, OAuthConfig + +logger = logging.getLogger(__name__) + + +class OAuthAccessTokenException(Exception): + ''' + oauth授权失败异常 + ''' + + +class BaseOauthManager(metaclass=ABCMeta): + """获取用户授权""" + AUTH_URL = None + """获取token""" + TOKEN_URL = None + """获取用户信息""" + API_URL = None + '''icon图标名''' + ICON_NAME = None + + def __init__(self, access_token=None, openid=None): + self.access_token = access_token + self.openid = openid + + @property + def is_access_token_set(self): + return self.access_token is not None + + @property + def is_authorized(self): + return self.is_access_token_set and self.access_token is not None and self.openid is not None + + @abstractmethod + def get_authorization_url(self, nexturl='/'): + pass + + @abstractmethod + def get_access_token_by_code(self, code): + pass + + @abstractmethod + def get_oauth_userinfo(self): + pass + + @abstractmethod + def get_picture(self, metadata): + pass + + def do_get(self, url, params, headers=None): + rsp = requests.get(url=url, params=params, headers=headers) + logger.info(rsp.text) + return rsp.text + + def do_post(self, url, params, headers=None): + rsp = requests.post(url, params, headers=headers) + logger.info(rsp.text) + return rsp.text + + def get_config(self): + value = OAuthConfig.objects.filter(type=self.ICON_NAME) + return value[0] if value else None + + +class WBOauthManager(BaseOauthManager): + AUTH_URL = 'https://api.weibo.com/oauth2/authorize' + TOKEN_URL = 'https://api.weibo.com/oauth2/access_token' + API_URL = 'https://api.weibo.com/2/users/show.json' + ICON_NAME = 'weibo' + + def __init__(self, access_token=None, openid=None): + config = self.get_config() + 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) + + def get_authorization_url(self, nexturl='/'): + params = { + 'client_id': self.client_id, + 'response_type': 'code', + 'redirect_uri': self.callback_url + '&next_url=' + nexturl + } + url = self.AUTH_URL + "?" + urllib.parse.urlencode(params) + return url + + def get_access_token_by_code(self, code): + + params = { + 'client_id': self.client_id, + 'client_secret': self.client_secret, + 'grant_type': 'authorization_code', + 'code': code, + 'redirect_uri': self.callback_url + } + rsp = self.do_post(self.TOKEN_URL, params) + + obj = json.loads(rsp) + if 'access_token' in obj: + self.access_token = str(obj['access_token']) + self.openid = str(obj['uid']) + return self.get_oauth_userinfo() + else: + raise OAuthAccessTokenException(rsp) + + def get_oauth_userinfo(self): + if not self.is_authorized: + return None + params = { + 'uid': self.openid, + 'access_token': self.access_token + } + rsp = self.do_get(self.API_URL, params) + try: + datas = json.loads(rsp) + user = OAuthUser() + user.metadata = rsp + user.picture = datas['avatar_large'] + user.nickname = datas['screen_name'] + user.openid = datas['id'] + user.type = 'weibo' + user.token = self.access_token + if 'email' in datas and datas['email']: + user.email = datas['email'] + return user + except Exception as e: + logger.error(e) + logger.error('weibo oauth error.rsp:' + rsp) + return None + + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['avatar_large'] + + +class ProxyManagerMixin: + def __init__(self, *args, **kwargs): + if os.environ.get("HTTP_PROXY"): + self.proxies = { + "http": os.environ.get("HTTP_PROXY"), + "https": os.environ.get("HTTP_PROXY") + } + else: + self.proxies = None + + def do_get(self, url, params, headers=None): + rsp = requests.get(url=url, params=params, headers=headers, proxies=self.proxies) + logger.info(rsp.text) + return rsp.text + + def do_post(self, url, params, headers=None): + rsp = requests.post(url, params, headers=headers, proxies=self.proxies) + logger.info(rsp.text) + return rsp.text + + +class GoogleOauthManager(ProxyManagerMixin, BaseOauthManager): + AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth' + TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token' + API_URL = 'https://www.googleapis.com/oauth2/v3/userinfo' + ICON_NAME = 'google' + + def __init__(self, access_token=None, openid=None): + config = self.get_config() + 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) + + def get_authorization_url(self, nexturl='/'): + params = { + 'client_id': self.client_id, + 'response_type': 'code', + 'redirect_uri': self.callback_url, + 'scope': 'openid email', + } + url = self.AUTH_URL + "?" + urllib.parse.urlencode(params) + return url + + def get_access_token_by_code(self, code): + params = { + 'client_id': self.client_id, + 'client_secret': self.client_secret, + 'grant_type': 'authorization_code', + 'code': code, + + 'redirect_uri': self.callback_url + } + rsp = self.do_post(self.TOKEN_URL, params) + + obj = json.loads(rsp) + + if 'access_token' in obj: + self.access_token = str(obj['access_token']) + self.openid = str(obj['id_token']) + logger.info(self.ICON_NAME + ' oauth ' + rsp) + return self.access_token + else: + raise OAuthAccessTokenException(rsp) + + def get_oauth_userinfo(self): + if not self.is_authorized: + return None + params = { + 'access_token': self.access_token + } + rsp = self.do_get(self.API_URL, params) + try: + + datas = json.loads(rsp) + user = OAuthUser() + user.metadata = rsp + user.picture = datas['picture'] + user.nickname = datas['name'] + user.openid = datas['sub'] + user.token = self.access_token + user.type = 'google' + if datas['email']: + user.email = datas['email'] + return user + except Exception as e: + logger.error(e) + logger.error('google oauth error.rsp:' + rsp) + return None + + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['picture'] + + +class GitHubOauthManager(ProxyManagerMixin, BaseOauthManager): + AUTH_URL = 'https://github.com/login/oauth/authorize' + TOKEN_URL = 'https://github.com/login/oauth/access_token' + API_URL = 'https://api.github.com/user' + ICON_NAME = 'github' + + def __init__(self, access_token=None, openid=None): + config = self.get_config() + 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) + + def get_authorization_url(self, next_url='/'): + params = { + 'client_id': self.client_id, + 'response_type': 'code', + 'redirect_uri': f'{self.callback_url}&next_url={next_url}', + 'scope': 'user' + } + url = self.AUTH_URL + "?" + urllib.parse.urlencode(params) + return url + + def get_access_token_by_code(self, code): + params = { + 'client_id': self.client_id, + 'client_secret': self.client_secret, + 'grant_type': 'authorization_code', + 'code': code, + + 'redirect_uri': self.callback_url + } + rsp = self.do_post(self.TOKEN_URL, params) + + from urllib import parse + r = parse.parse_qs(rsp) + if 'access_token' in r: + self.access_token = (r['access_token'][0]) + return self.access_token + else: + raise OAuthAccessTokenException(rsp) + + def get_oauth_userinfo(self): + + rsp = self.do_get(self.API_URL, params={}, headers={ + "Authorization": "token " + self.access_token + }) + try: + datas = json.loads(rsp) + user = OAuthUser() + user.picture = datas['avatar_url'] + user.nickname = datas['name'] + user.openid = datas['id'] + user.type = 'github' + user.token = self.access_token + user.metadata = rsp + if 'email' in datas and datas['email']: + user.email = datas['email'] + return user + except Exception as e: + logger.error(e) + logger.error('github oauth error.rsp:' + rsp) + return None + + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['avatar_url'] + + +class FaceBookOauthManager(ProxyManagerMixin, BaseOauthManager): + AUTH_URL = 'https://www.facebook.com/v16.0/dialog/oauth' + TOKEN_URL = 'https://graph.facebook.com/v16.0/oauth/access_token' + API_URL = 'https://graph.facebook.com/me' + ICON_NAME = 'facebook' + + def __init__(self, access_token=None, openid=None): + config = self.get_config() + 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) + + def get_authorization_url(self, next_url='/'): + params = { + 'client_id': self.client_id, + 'response_type': 'code', + 'redirect_uri': self.callback_url, + 'scope': 'email,public_profile' + } + url = self.AUTH_URL + "?" + urllib.parse.urlencode(params) + return url + + def get_access_token_by_code(self, code): + params = { + 'client_id': self.client_id, + 'client_secret': self.client_secret, + # 'grant_type': 'authorization_code', + 'code': code, + + 'redirect_uri': self.callback_url + } + rsp = self.do_post(self.TOKEN_URL, params) + + obj = json.loads(rsp) + if 'access_token' in obj: + token = str(obj['access_token']) + self.access_token = token + return self.access_token + else: + raise OAuthAccessTokenException(rsp) + + def get_oauth_userinfo(self): + params = { + 'access_token': self.access_token, + 'fields': 'id,name,picture,email' + } + try: + rsp = self.do_get(self.API_URL, params) + datas = json.loads(rsp) + user = OAuthUser() + user.nickname = datas['name'] + user.openid = datas['id'] + user.type = 'facebook' + user.token = self.access_token + user.metadata = rsp + if 'email' in datas and datas['email']: + user.email = datas['email'] + if 'picture' in datas and datas['picture'] and datas['picture']['data'] and datas['picture']['data']['url']: + user.picture = str(datas['picture']['data']['url']) + return user + except Exception as e: + logger.error(e) + return None + + def get_picture(self, metadata): + datas = json.loads(metadata) + return str(datas['picture']['data']['url']) + + +class QQOauthManager(BaseOauthManager): + AUTH_URL = 'https://graph.qq.com/oauth2.0/authorize' + TOKEN_URL = 'https://graph.qq.com/oauth2.0/token' + API_URL = 'https://graph.qq.com/user/get_user_info' + OPEN_ID_URL = 'https://graph.qq.com/oauth2.0/me' + ICON_NAME = 'qq' + + def __init__(self, access_token=None, openid=None): + config = self.get_config() + 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) + + def get_authorization_url(self, next_url='/'): + params = { + 'response_type': 'code', + 'client_id': self.client_id, + 'redirect_uri': self.callback_url + '&next_url=' + next_url, + } + url = self.AUTH_URL + "?" + urllib.parse.urlencode(params) + return url + + def get_access_token_by_code(self, code): + params = { + 'grant_type': 'authorization_code', + 'client_id': self.client_id, + 'client_secret': self.client_secret, + 'code': code, + 'redirect_uri': self.callback_url + } + rsp = self.do_get(self.TOKEN_URL, params) + if rsp: + d = urllib.parse.parse_qs(rsp) + if 'access_token' in d: + token = d['access_token'] + self.access_token = token[0] + return token + else: + raise OAuthAccessTokenException(rsp) + + def get_open_id(self): + if self.is_access_token_set: + params = { + 'access_token': self.access_token + } + rsp = self.do_get(self.OPEN_ID_URL, params) + if rsp: + rsp = rsp.replace( + 'callback(', '').replace( + ')', '').replace( + ';', '') + obj = json.loads(rsp) + openid = str(obj['openid']) + self.openid = openid + return openid + + def get_oauth_userinfo(self): + openid = self.get_open_id() + if openid: + params = { + 'access_token': self.access_token, + 'oauth_consumer_key': self.client_id, + 'openid': self.openid + } + rsp = self.do_get(self.API_URL, params) + logger.info(rsp) + obj = json.loads(rsp) + user = OAuthUser() + user.nickname = obj['nickname'] + user.openid = openid + user.type = 'qq' + user.token = self.access_token + user.metadata = rsp + if 'email' in obj: + user.email = obj['email'] + if 'figureurl' in obj: + user.picture = str(obj['figureurl']) + return user + + def get_picture(self, metadata): + datas = json.loads(metadata) + return str(datas['figureurl']) + + +@cache_decorator(expiration=100 * 60) +def get_oauth_apps(): + configs = OAuthConfig.objects.filter(is_enable=True).all() + if not configs: + return [] + configtypes = [x.type for x in configs] + applications = BaseOauthManager.__subclasses__() + apps = [x() for x in applications if x().ICON_NAME.lower() in configtypes] + return 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)) + if finds: + return finds[0] + return None diff --git a/oauth/templatetags/__init__.py b/oauth/templatetags/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/oauth/templatetags/__init__.py @@ -0,0 +1 @@ + diff --git a/oauth/templatetags/oauth_tags.py b/oauth/templatetags/oauth_tags.py new file mode 100644 index 0000000..7b687d5 --- /dev/null +++ b/oauth/templatetags/oauth_tags.py @@ -0,0 +1,22 @@ +from django import template +from django.urls import reverse + +from oauth.oauthmanager import get_oauth_apps + +register = template.Library() + + +@register.inclusion_tag('oauth/oauth_applications.html') +def load_oauth_applications(request): + applications = get_oauth_apps() + if applications: + 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)) + else: + apps = [] + return { + 'apps': apps + } diff --git a/oauth/tests.py b/oauth/tests.py new file mode 100644 index 0000000..bb23b9b --- /dev/null +++ b/oauth/tests.py @@ -0,0 +1,249 @@ +import json +from unittest.mock import patch + +from django.conf import settings +from django.contrib import auth +from django.test import Client, RequestFactory, TestCase +from django.urls import reverse + +from djangoblog.utils import get_sha256 +from oauth.models import OAuthConfig +from oauth.oauthmanager import BaseOauthManager + + +# Create your tests here. +class OAuthConfigTest(TestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + + def test_oauth_login_test(self): + c = OAuthConfig() + c.type = 'weibo' + c.appkey = 'appkey' + c.appsecret = 'appsecret' + c.save() + + response = self.client.get('/oauth/oauthlogin?type=weibo') + self.assertEqual(response.status_code, 302) + self.assertTrue("api.weibo.com" in response.url) + + response = self.client.get('/oauth/authorize?type=weibo&code=code') + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/') + + +class OauthLoginTest(TestCase): + def setUp(self) -> None: + self.client = Client() + self.factory = RequestFactory() + self.apps = self.init_apps() + + def init_apps(self): + applications = [p() for p in BaseOauthManager.__subclasses__()] + for application in applications: + c = OAuthConfig() + c.type = application.ICON_NAME.lower() + c.appkey = 'appkey' + c.appsecret = 'appsecret' + c.save() + return applications + + def get_app_by_type(self, type): + for app in self.apps: + if app.ICON_NAME.lower() == type: + return app + + @patch("oauth.oauthmanager.WBOauthManager.do_post") + @patch("oauth.oauthmanager.WBOauthManager.do_get") + def test_weibo_login(self, mock_do_get, mock_do_post): + weibo_app = self.get_app_by_type('weibo') + assert weibo_app + url = weibo_app.get_authorization_url() + mock_do_post.return_value = json.dumps({"access_token": "access_token", + "uid": "uid" + }) + mock_do_get.return_value = json.dumps({ + "avatar_large": "avatar_large", + "screen_name": "screen_name", + "id": "id", + "email": "email", + }) + userinfo = weibo_app.get_access_token_by_code('code') + self.assertEqual(userinfo.token, 'access_token') + self.assertEqual(userinfo.openid, 'id') + + @patch("oauth.oauthmanager.GoogleOauthManager.do_post") + @patch("oauth.oauthmanager.GoogleOauthManager.do_get") + def test_google_login(self, mock_do_get, mock_do_post): + google_app = self.get_app_by_type('google') + assert google_app + url = google_app.get_authorization_url() + mock_do_post.return_value = json.dumps({ + "access_token": "access_token", + "id_token": "id_token", + }) + mock_do_get.return_value = json.dumps({ + "picture": "picture", + "name": "name", + "sub": "sub", + "email": "email", + }) + token = google_app.get_access_token_by_code('code') + userinfo = google_app.get_oauth_userinfo() + self.assertEqual(userinfo.token, 'access_token') + self.assertEqual(userinfo.openid, 'sub') + + @patch("oauth.oauthmanager.GitHubOauthManager.do_post") + @patch("oauth.oauthmanager.GitHubOauthManager.do_get") + def test_github_login(self, mock_do_get, mock_do_post): + github_app = self.get_app_by_type('github') + assert github_app + url = github_app.get_authorization_url() + self.assertTrue("github.com" in url) + self.assertTrue("client_id" in url) + mock_do_post.return_value = "access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&scope=repo%2Cgist&token_type=bearer" + mock_do_get.return_value = json.dumps({ + "avatar_url": "avatar_url", + "name": "name", + "id": "id", + "email": "email", + }) + token = github_app.get_access_token_by_code('code') + userinfo = github_app.get_oauth_userinfo() + self.assertEqual(userinfo.token, 'gho_16C7e42F292c6912E7710c838347Ae178B4a') + self.assertEqual(userinfo.openid, 'id') + + @patch("oauth.oauthmanager.FaceBookOauthManager.do_post") + @patch("oauth.oauthmanager.FaceBookOauthManager.do_get") + def test_facebook_login(self, mock_do_get, mock_do_post): + facebook_app = self.get_app_by_type('facebook') + assert facebook_app + url = facebook_app.get_authorization_url() + self.assertTrue("facebook.com" in url) + mock_do_post.return_value = json.dumps({ + "access_token": "access_token", + }) + mock_do_get.return_value = json.dumps({ + "name": "name", + "id": "id", + "email": "email", + "picture": { + "data": { + "url": "url" + } + } + }) + token = facebook_app.get_access_token_by_code('code') + userinfo = facebook_app.get_oauth_userinfo() + self.assertEqual(userinfo.token, 'access_token') + + @patch("oauth.oauthmanager.QQOauthManager.do_get", side_effect=[ + 'access_token=access_token&expires_in=3600', + 'callback({"client_id":"appid","openid":"openid"} );', + json.dumps({ + "nickname": "nickname", + "email": "email", + "figureurl": "figureurl", + "openid": "openid", + }) + ]) + def test_qq_login(self, mock_do_get): + qq_app = self.get_app_by_type('qq') + assert qq_app + url = qq_app.get_authorization_url() + self.assertTrue("qq.com" in url) + token = qq_app.get_access_token_by_code('code') + userinfo = qq_app.get_oauth_userinfo() + self.assertEqual(userinfo.token, 'access_token') + + @patch("oauth.oauthmanager.WBOauthManager.do_post") + @patch("oauth.oauthmanager.WBOauthManager.do_get") + def test_weibo_authoriz_login_with_email(self, mock_do_get, mock_do_post): + + mock_do_post.return_value = json.dumps({"access_token": "access_token", + "uid": "uid" + }) + mock_user_info = { + "avatar_large": "avatar_large", + "screen_name": "screen_name1", + "id": "id", + "email": "email", + } + mock_do_get.return_value = json.dumps(mock_user_info) + + response = self.client.get('/oauth/oauthlogin?type=weibo') + self.assertEqual(response.status_code, 302) + self.assertTrue("api.weibo.com" in response.url) + + response = self.client.get('/oauth/authorize?type=weibo&code=code') + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/') + + user = auth.get_user(self.client) + assert user.is_authenticated + self.assertTrue(user.is_authenticated) + self.assertEqual(user.username, mock_user_info['screen_name']) + self.assertEqual(user.email, mock_user_info['email']) + self.client.logout() + + response = self.client.get('/oauth/authorize?type=weibo&code=code') + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/') + + user = auth.get_user(self.client) + assert user.is_authenticated + self.assertTrue(user.is_authenticated) + self.assertEqual(user.username, mock_user_info['screen_name']) + self.assertEqual(user.email, mock_user_info['email']) + + @patch("oauth.oauthmanager.WBOauthManager.do_post") + @patch("oauth.oauthmanager.WBOauthManager.do_get") + def test_weibo_authoriz_login_without_email(self, mock_do_get, mock_do_post): + + mock_do_post.return_value = json.dumps({"access_token": "access_token", + "uid": "uid" + }) + mock_user_info = { + "avatar_large": "avatar_large", + "screen_name": "screen_name1", + "id": "id", + } + mock_do_get.return_value = json.dumps(mock_user_info) + + response = self.client.get('/oauth/oauthlogin?type=weibo') + self.assertEqual(response.status_code, 302) + self.assertTrue("api.weibo.com" in response.url) + + response = self.client.get('/oauth/authorize?type=weibo&code=code') + + self.assertEqual(response.status_code, 302) + + oauth_user_id = int(response.url.split('/')[-1].split('.')[0]) + self.assertEqual(response.url, f'/oauth/requireemail/{oauth_user_id}.html') + + response = self.client.post(response.url, {'email': 'test@gmail.com', 'oauthid': oauth_user_id}) + + self.assertEqual(response.status_code, 302) + sign = get_sha256(settings.SECRET_KEY + + str(oauth_user_id) + settings.SECRET_KEY) + + url = reverse('oauth:bindsuccess', kwargs={ + 'oauthid': oauth_user_id, + }) + self.assertEqual(response.url, f'{url}?type=email') + + path = reverse('oauth:email_confirm', kwargs={ + 'id': oauth_user_id, + 'sign': sign + }) + response = self.client.get(path) + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, f'/oauth/bindsuccess/{oauth_user_id}.html?type=success') + user = auth.get_user(self.client) + from oauth.models import OAuthUser + oauth_user = OAuthUser.objects.get(author=user) + self.assertTrue(user.is_authenticated) + self.assertEqual(user.username, mock_user_info['screen_name']) + self.assertEqual(user.email, 'test@gmail.com') + self.assertEqual(oauth_user.pk, oauth_user_id) diff --git a/oauth/urls.py b/oauth/urls.py new file mode 100644 index 0000000..c4a12a0 --- /dev/null +++ b/oauth/urls.py @@ -0,0 +1,25 @@ +from django.urls import path + +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')] diff --git a/oauth/views.py b/oauth/views.py new file mode 100644 index 0000000..12e3a6e --- /dev/null +++ b/oauth/views.py @@ -0,0 +1,253 @@ +import logging +# Create your views here. +from urllib.parse import urlparse + +from django.conf import settings +from django.contrib.auth import get_user_model +from django.contrib.auth import login +from django.core.exceptions import ObjectDoesNotExist +from django.db import transaction +from django.http import HttpResponseForbidden +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.shortcuts import render +from django.urls import reverse +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from django.views.generic import FormView + +from djangoblog.blog_signals import oauth_user_login_signal +from djangoblog.utils import get_current_site +from djangoblog.utils import send_email, get_sha256 +from oauth.forms import RequireEmailForm +from .models import OAuthUser +from .oauthmanager import get_manager_by_type, OAuthAccessTokenException + +logger = logging.getLogger(__name__) + + +def get_redirecturl(request): + nexturl = request.GET.get('next_url', None) + if not nexturl or nexturl == '/login/' or nexturl == '/login': + nexturl = '/' + return nexturl + p = urlparse(nexturl) + if p.netloc: + site = get_current_site().domain + if not p.netloc.replace('www.', '') == site.replace('www.', ''): + logger.info('非法url:' + nexturl) + return "/" + return nexturl + + +def oauthlogin(request): + type = request.GET.get('type', None) + if not type: + return HttpResponseRedirect('/') + manager = get_manager_by_type(type) + if not manager: + return HttpResponseRedirect('/') + nexturl = get_redirecturl(request) + authorizeurl = manager.get_authorization_url(nexturl) + return HttpResponseRedirect(authorizeurl) + + +def authorize(request): + type = request.GET.get('type', None) + if not type: + return HttpResponseRedirect('/') + manager = get_manager_by_type(type) + if not manager: + return HttpResponseRedirect('/') + code = request.GET.get('code', None) + try: + rsp = manager.get_access_token_by_code(code) + except OAuthAccessTokenException as e: + logger.warning("OAuthAccessTokenException:" + str(e)) + return HttpResponseRedirect('/') + except Exception as e: + logger.error(e) + rsp = None + nexturl = get_redirecturl(request) + if not rsp: + return HttpResponseRedirect(manager.get_authorization_url(nexturl)) + user = manager.get_oauth_userinfo() + if user: + if not user.nickname or not user.nickname.strip(): + user.nickname = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') + try: + temp = OAuthUser.objects.get(type=type, openid=user.openid) + temp.picture = user.picture + temp.metadata = user.metadata + temp.nickname = user.nickname + user = temp + except ObjectDoesNotExist: + pass + # facebook的token过长 + if type == 'facebook': + user.token = '' + if user.email: + with transaction.atomic(): + author = None + try: + author = get_user_model().objects.get(id=user.author_id) + except ObjectDoesNotExist: + pass + if not author: + result = get_user_model().objects.get_or_create(email=user.email) + author = result[0] + if result[1]: + try: + get_user_model().objects.get(username=user.nickname) + except ObjectDoesNotExist: + author.username = user.nickname + else: + author.username = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') + author.source = 'authorize' + author.save() + + user.author = author + user.save() + + oauth_user_login_signal.send( + sender=authorize.__class__, id=user.id) + login(request, author) + return HttpResponseRedirect(nexturl) + else: + user.save() + url = reverse('oauth:require_email', kwargs={ + 'oauthid': user.id + }) + + return HttpResponseRedirect(url) + else: + return HttpResponseRedirect(nexturl) + + +def emailconfirm(request, id, sign): + if not sign: + return HttpResponseForbidden() + if not get_sha256(settings.SECRET_KEY + + str(id) + + settings.SECRET_KEY).upper() == sign.upper(): + return HttpResponseForbidden() + oauthuser = get_object_or_404(OAuthUser, pk=id) + with transaction.atomic(): + if oauthuser.author: + author = get_user_model().objects.get(pk=oauthuser.author_id) + else: + result = get_user_model().objects.get_or_create(email=oauthuser.email) + author = result[0] + if result[1]: + author.source = 'emailconfirm' + author.username = oauthuser.nickname.strip() if oauthuser.nickname.strip( + ) else "djangoblog" + timezone.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) + login(request, author) + + site = 'http://' + get_current_site().domain + content = _(''' +

Congratulations, you have successfully bound your email address. You can use + %(oauthuser_type)s to directly log in to this website without a password.

+ You are welcome to continue to follow this site, the address is + %(site)s + Thank you again! +
+ If the link above cannot be opened, please copy this link to your browser. + %(site)s + ''') % {'oauthuser_type': oauthuser.type, 'site': site} + + send_email(emailto=[oauthuser.email, ], title=_('Congratulations on your successful binding!'), content=content) + url = reverse('oauth:bindsuccess', kwargs={ + 'oauthid': id + }) + url = url + '?type=success' + return HttpResponseRedirect(url) + + +class RequireEmailView(FormView): + form_class = RequireEmailForm + template_name = 'oauth/require_email.html' + + def get(self, request, *args, **kwargs): + oauthid = self.kwargs['oauthid'] + oauthuser = get_object_or_404(OAuthUser, pk=oauthid) + if oauthuser.email: + pass + # return HttpResponseRedirect('/') + + return super(RequireEmailView, self).get(request, *args, **kwargs) + + def get_initial(self): + oauthid = self.kwargs['oauthid'] + return { + 'email': '', + 'oauthid': oauthid + } + + def get_context_data(self, **kwargs): + oauthid = self.kwargs['oauthid'] + oauthuser = get_object_or_404(OAuthUser, pk=oauthid) + if oauthuser.picture: + kwargs['picture'] = oauthuser.picture + return super(RequireEmailView, self).get_context_data(**kwargs) + + def form_valid(self, form): + email = form.cleaned_data['email'] + oauthid = form.cleaned_data['oauthid'] + oauthuser = get_object_or_404(OAuthUser, pk=oauthid) + oauthuser.email = email + oauthuser.save() + sign = get_sha256(settings.SECRET_KEY + + str(oauthuser.id) + settings.SECRET_KEY) + site = get_current_site().domain + if settings.DEBUG: + site = '127.0.0.1:8000' + path = reverse('oauth:email_confirm', kwargs={ + 'id': oauthid, + 'sign': sign + }) + url = "http://{site}{path}".format(site=site, path=path) + + content = _(""" +

Please click the link below to bind your email

+ + %(url)s + + Thank you again! +
+ If the link above cannot be opened, please copy this link to your browser. +
+ %(url)s + """) % {'url': url} + send_email(emailto=[email, ], title=_('Bind your email'), content=content) + url = reverse('oauth:bindsuccess', kwargs={ + 'oauthid': oauthid + }) + url = url + '?type=email' + return HttpResponseRedirect(url) + + +def bindsuccess(request, oauthid): + type = request.GET.get('type', None) + oauthuser = get_object_or_404(OAuthUser, pk=oauthid) + if type == 'email': + title = _('Bind your email') + content = _( + 'Congratulations, the binding is just one step away. ' + 'Please log in to your email to check the email to complete the binding. Thank you.') + else: + title = _('Binding successful') + content = _( + "Congratulations, you have successfully bound your email address. You can use %(oauthuser_type)s" + " to directly log in to this website without a password. You are welcome to continue to follow this site." % { + 'oauthuser_type': oauthuser.type}) + return render(request, 'oauth/bindsuccess.html', { + 'title': title, + 'content': content + }) diff --git a/owntracks/__init__.py b/owntracks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/owntracks/admin.py b/owntracks/admin.py new file mode 100644 index 0000000..655b535 --- /dev/null +++ b/owntracks/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin + +# Register your models here. + + +class OwnTrackLogsAdmin(admin.ModelAdmin): + pass diff --git a/owntracks/apps.py b/owntracks/apps.py new file mode 100644 index 0000000..1bc5f12 --- /dev/null +++ b/owntracks/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class OwntracksConfig(AppConfig): + name = 'owntracks' diff --git a/owntracks/migrations/0001_initial.py b/owntracks/migrations/0001_initial.py new file mode 100644 index 0000000..9eee55c --- /dev/null +++ b/owntracks/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='OwnTrackLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tid', models.CharField(max_length=100, verbose_name='用户')), + ('lat', models.FloatField(verbose_name='纬度')), + ('lon', models.FloatField(verbose_name='经度')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ], + options={ + 'verbose_name': 'OwnTrackLogs', + 'verbose_name_plural': 'OwnTrackLogs', + 'ordering': ['created_time'], + 'get_latest_by': 'created_time', + }, + ), + ] diff --git a/owntracks/migrations/0002_alter_owntracklog_options_and_more.py b/owntracks/migrations/0002_alter_owntracklog_options_and_more.py new file mode 100644 index 0000000..b4f8dec --- /dev/null +++ b/owntracks/migrations/0002_alter_owntracklog_options_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('owntracks', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='owntracklog', + options={'get_latest_by': 'creation_time', 'ordering': ['creation_time'], 'verbose_name': 'OwnTrackLogs', 'verbose_name_plural': 'OwnTrackLogs'}, + ), + migrations.RenameField( + model_name='owntracklog', + old_name='created_time', + new_name='creation_time', + ), + ] diff --git a/owntracks/migrations/__init__.py b/owntracks/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/owntracks/models.py b/owntracks/models.py new file mode 100644 index 0000000..760942c --- /dev/null +++ b/owntracks/models.py @@ -0,0 +1,20 @@ +from django.db import models +from django.utils.timezone import now + + +# Create your models here. + +class OwnTrackLog(models.Model): + tid = models.CharField(max_length=100, null=False, verbose_name='用户') + lat = models.FloatField(verbose_name='纬度') + lon = models.FloatField(verbose_name='经度') + creation_time = models.DateTimeField('创建时间', default=now) + + def __str__(self): + return self.tid + + class Meta: + ordering = ['creation_time'] + verbose_name = "OwnTrackLogs" + verbose_name_plural = verbose_name + get_latest_by = 'creation_time' diff --git a/owntracks/tests.py b/owntracks/tests.py new file mode 100644 index 0000000..3b4b9d8 --- /dev/null +++ b/owntracks/tests.py @@ -0,0 +1,64 @@ +import json + +from django.test import Client, RequestFactory, TestCase + +from accounts.models import BlogUser +from .models import OwnTrackLog + + +# Create your tests here. + +class OwnTrackLogTest(TestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + + def test_own_track_log(self): + o = { + 'tid': 12, + 'lat': 123.123, + 'lon': 134.341 + } + + self.client.post( + '/owntracks/logtracks', + json.dumps(o), + content_type='application/json') + length = len(OwnTrackLog.objects.all()) + self.assertEqual(length, 1) + + o = { + 'tid': 12, + 'lat': 123.123 + } + + 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") + + self.client.login(username='liangliangyy1', password='liangliangyy1') + s = OwnTrackLog() + s.tid = 12 + s.lon = 123.234 + s.lat = 34.234 + s.save() + + rsp = self.client.get('/owntracks/show_dates') + self.assertEqual(rsp.status_code, 200) + rsp = self.client.get('/owntracks/show_maps') + self.assertEqual(rsp.status_code, 200) + rsp = self.client.get('/owntracks/get_datas') + self.assertEqual(rsp.status_code, 200) + rsp = self.client.get('/owntracks/get_datas?date=2018-02-26') + self.assertEqual(rsp.status_code, 200) diff --git a/owntracks/urls.py b/owntracks/urls.py new file mode 100644 index 0000000..c19ada8 --- /dev/null +++ b/owntracks/urls.py @@ -0,0 +1,12 @@ +from django.urls import path + +from . import views + +app_name = "owntracks" + +urlpatterns = [ + path('owntracks/logtracks', views.manage_owntrack_log, name='logtracks'), + path('owntracks/show_maps', views.show_maps, name='show_maps'), + path('owntracks/get_datas', views.get_datas, name='get_datas'), + path('owntracks/show_dates', views.show_log_dates, name='show_dates') +] diff --git a/owntracks/views.py b/owntracks/views.py new file mode 100644 index 0000000..4c72bdd --- /dev/null +++ b/owntracks/views.py @@ -0,0 +1,127 @@ +# Create your views here. +import datetime +import itertools +import json +import logging +from datetime import timezone +from itertools import groupby + +import django +import requests +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +from django.http import JsonResponse +from django.shortcuts import render +from django.views.decorators.csrf import csrf_exempt + +from .models import OwnTrackLog + +logger = logging.getLogger(__name__) + + +@csrf_exempt +def manage_owntrack_log(request): + try: + s = json.loads(request.read().decode('utf-8')) + tid = s['tid'] + lat = s['lat'] + lon = s['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 + m.lat = lat + m.lon = lon + m.save() + return HttpResponse('ok') + else: + return HttpResponse('data error') + except Exception as e: + logger.error(e) + return HttpResponse('error') + + +@login_required +def show_maps(request): + if request.user.is_superuser: + defaultdate = str(datetime.datetime.now(timezone.utc).date()) + date = request.GET.get('date', defaultdate) + context = { + 'date': date + } + return render(request, 'owntracks/show_maps.html', context) + else: + from django.http import HttpResponseForbidden + return HttpResponseForbidden() + + +@login_required +def show_log_dates(request): + dates = OwnTrackLog.objects.values_list('creation_time', flat=True) + results = list(sorted(set(map(lambda x: x.strftime('%Y-%m-%d'), dates)))) + + context = { + 'results': results + } + return render(request, 'owntracks/show_log_dates.html', context) + + +def convert_to_amap(locations): + convert_result = [] + it = iter(locations) + + item = list(itertools.islice(it, 30)) + while 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' + query = { + 'key': key, + 'locations': datas, + 'coordsys': 'gps' + } + rsp = requests.get(url=api, params=query) + result = json.loads(rsp.text) + if "locations" in result: + convert_result.append(result['locations']) + item = list(itertools.islice(it, 30)) + + return ";".join(convert_result) + + +@login_required +def get_datas(request): + now = django.utils.timezone.now().replace(tzinfo=timezone.utc) + 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) + nextdate = querydate + datetime.timedelta(days=1) + models = OwnTrackLog.objects.filter( + creation_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): + + d = dict() + d["name"] = tid + paths = list() + # 使用高德转换后的经纬度 + # locations = convert_to_amap( + # sorted(item, key=lambda x: x.creation_time)) + # for i in locations.split(';'): + # paths.append(i.split(',')) + # 使用GPS原始经纬度 + for location in sorted(item, key=lambda x: x.creation_time): + paths.append([str(location.lon), str(location.lat)]) + d["path"] = paths + result.append(d) + return JsonResponse(result, safe=False) diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 0000000..e88afca --- /dev/null +++ b/plugins/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package diff --git a/plugins/article_copyright/__init__.py b/plugins/article_copyright/__init__.py new file mode 100644 index 0000000..e88afca --- /dev/null +++ b/plugins/article_copyright/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package diff --git a/plugins/article_copyright/plugin.py b/plugins/article_copyright/plugin.py new file mode 100644 index 0000000..317fed2 --- /dev/null +++ b/plugins/article_copyright/plugin.py @@ -0,0 +1,32 @@ +from djangoblog.plugin_manage.base_plugin import BasePlugin +from djangoblog.plugin_manage import hooks +from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME + + +class ArticleCopyrightPlugin(BasePlugin): + PLUGIN_NAME = '文章结尾版权声明' + PLUGIN_DESCRIPTION = '一个在文章正文末尾添加版权声明的插件。' + PLUGIN_VERSION = '0.2.0' + PLUGIN_AUTHOR = 'liangliangyy' + + # 2. 实现 register_hooks 方法,专门用于注册钩子 + def register_hooks(self): + # 在这里将插件的方法注册到指定的钩子上 + hooks.register(ARTICLE_CONTENT_HOOK_NAME, self.add_copyright_to_content) + + def add_copyright_to_content(self, content, *args, **kwargs): + """ + 这个方法会被注册到 'the_content' 过滤器钩子上。 + 它接收原始内容,并返回添加了版权信息的新内容。 + """ + article = kwargs.get('article') + if not article: + return content + + copyright_info = f"\n

本文由 {article.author.username} 原创,转载请注明出处。

" + return content + copyright_info + + +# 3. 实例化插件。 +# 这会自动调用 BasePlugin.__init__,然后 BasePlugin.__init__ 会调用我们上面定义的 register_hooks 方法。 +plugin = ArticleCopyrightPlugin() diff --git a/plugins/external_links/__init__.py b/plugins/external_links/__init__.py new file mode 100644 index 0000000..e88afca --- /dev/null +++ b/plugins/external_links/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package diff --git a/plugins/external_links/plugin.py b/plugins/external_links/plugin.py new file mode 100644 index 0000000..5b2ef14 --- /dev/null +++ b/plugins/external_links/plugin.py @@ -0,0 +1,48 @@ +import re +from urllib.parse import urlparse +from djangoblog.plugin_manage.base_plugin import BasePlugin +from djangoblog.plugin_manage import hooks +from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME + + +class ExternalLinksPlugin(BasePlugin): + PLUGIN_NAME = '外部链接处理器' + PLUGIN_DESCRIPTION = '自动为文章中的外部链接添加 target="_blank" 和 rel="noopener noreferrer" 属性。' + PLUGIN_VERSION = '0.1.0' + PLUGIN_AUTHOR = 'liangliangyy' + + def register_hooks(self): + hooks.register(ARTICLE_CONTENT_HOOK_NAME, self.process_external_links) + + def process_external_links(self, content, *args, **kwargs): + from djangoblog.utils import get_current_site + site_domain = get_current_site().domain + + # 正则表达式查找所有 标签 + link_pattern = re.compile(r'(]*?\s+)?href=")([^"]*)(".*?/a>)', re.IGNORECASE) + + def replacer(match): + # match.group(1) 是 ... + href = match.group(2) + + # 如果链接已经有 target 属性,则不处理 + if 'target=' in match.group(0).lower(): + return match.group(0) + + # 解析链接 + parsed_url = urlparse(href) + + # 如果链接是外部的 (有域名且域名不等于当前网站域名) + if parsed_url.netloc and parsed_url.netloc != site_domain: + # 添加 target 和 rel 属性 + return f'{match.group(1)}{href}" target="_blank" rel="noopener noreferrer"{match.group(3)}' + + # 否则返回原样 + return match.group(0) + + return link_pattern.sub(replacer, content) + + +plugin = ExternalLinksPlugin() diff --git a/plugins/reading_time/__init__.py b/plugins/reading_time/__init__.py new file mode 100644 index 0000000..e88afca --- /dev/null +++ b/plugins/reading_time/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package diff --git a/plugins/reading_time/plugin.py b/plugins/reading_time/plugin.py new file mode 100644 index 0000000..35f9db1 --- /dev/null +++ b/plugins/reading_time/plugin.py @@ -0,0 +1,43 @@ +import math +import re +from djangoblog.plugin_manage.base_plugin import BasePlugin +from djangoblog.plugin_manage import hooks +from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME + + +class ReadingTimePlugin(BasePlugin): + PLUGIN_NAME = '阅读时间预测' + PLUGIN_DESCRIPTION = '估算文章阅读时间并显示在文章开头。' + PLUGIN_VERSION = '0.1.0' + PLUGIN_AUTHOR = 'liangliangyy' + + def register_hooks(self): + hooks.register(ARTICLE_CONTENT_HOOK_NAME, self.add_reading_time) + + def add_reading_time(self, content, *args, **kwargs): + """ + 计算阅读时间并添加到内容开头。 + """ + # 移除HTML标签和空白字符,以获得纯文本 + clean_content = re.sub(r'<[^>]*>', '', content) + clean_content = clean_content.strip() + + # 中文和英文单词混合计数的一个简单方法 + # 匹配中文字符或连续的非中文字符(视为单词) + words = re.findall(r'[\u4e00-\u9fa5]|\w+', clean_content) + word_count = len(words) + + # 按平均每分钟200字的速度计算 + reading_speed = 200 + reading_minutes = math.ceil(word_count / reading_speed) + + # 如果阅读时间少于1分钟,则显示为1分钟 + if reading_minutes < 1: + reading_minutes = 1 + + reading_time_html = f'

预计阅读时间:{reading_minutes} 分钟

' + + return reading_time_html + content + + +plugin = ReadingTimePlugin() \ No newline at end of file diff --git a/plugins/seo_optimizer/__init__.py b/plugins/seo_optimizer/__init__.py new file mode 100644 index 0000000..e88afca --- /dev/null +++ b/plugins/seo_optimizer/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package diff --git a/plugins/seo_optimizer/plugin.py b/plugins/seo_optimizer/plugin.py new file mode 100644 index 0000000..b5b19a3 --- /dev/null +++ b/plugins/seo_optimizer/plugin.py @@ -0,0 +1,142 @@ +import json +from django.utils.html import strip_tags +from django.template.defaultfilters import truncatewords +from djangoblog.plugin_manage.base_plugin import BasePlugin +from djangoblog.plugin_manage import hooks +from blog.models import Article, Category, Tag +from djangoblog.utils import get_blog_setting + + +class SeoOptimizerPlugin(BasePlugin): + PLUGIN_NAME = 'SEO 优化器' + PLUGIN_DESCRIPTION = '为文章、页面等提供 SEO 优化,动态生成 meta 标签和 JSON-LD 结构化数据。' + PLUGIN_VERSION = '0.2.0' + PLUGIN_AUTHOR = 'liuangliangyy' + + def register_hooks(self): + hooks.register('head_meta', self.dispatch_seo_generation) + + def _get_article_seo_data(self, context, request, blog_setting): + article = context.get('article') + if not isinstance(article, Article): + return None + + description = strip_tags(article.body)[:150] + keywords = ",".join([tag.name for tag in article.tags.all()]) or blog_setting.site_keywords + + meta_tags = f''' + + + + + + + + + ''' + for tag in article.tags.all(): + meta_tags += f'' + meta_tags += f'' + + structured_data = { + "@context": "https://schema.org", + "@type": "Article", + "mainEntityOfPage": {"@type": "WebPage", "@id": request.build_absolute_uri()}, + "headline": article.title, + "description": description, + "image": request.build_absolute_uri(article.get_first_image_url()), + "datePublished": article.pub_time.isoformat(), + "dateModified": article.last_modify_time.isoformat(), + "author": {"@type": "Person", "name": article.author.username}, + "publisher": {"@type": "Organization", "name": blog_setting.site_name} + } + if not structured_data.get("image"): + del structured_data["image"] + + return { + "title": f"{article.title} | {blog_setting.site_name}", + "description": description, + "keywords": keywords, + "meta_tags": meta_tags, + "json_ld": structured_data + } + + def _get_category_seo_data(self, context, request, blog_setting): + category_name = context.get('tag_name') + if not category_name: + return None + + category = Category.objects.filter(name=category_name).first() + if not category: + return None + + title = f"{category.name} | {blog_setting.site_name}" + description = strip_tags(category.name) or blog_setting.site_description + keywords = category.name + + # BreadcrumbList structured data for category page + breadcrumb_items = [{"@type": "ListItem", "position": 1, "name": "首页", "item": request.build_absolute_uri('/')}] + breadcrumb_items.append({"@type": "ListItem", "position": 2, "name": category.name, "item": request.build_absolute_uri()}) + + structured_data = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + "itemListElement": breadcrumb_items + } + + return { + "title": title, + "description": description, + "keywords": keywords, + "meta_tags": "", + "json_ld": structured_data + } + + def _get_default_seo_data(self, context, request, blog_setting): + # Homepage and other default pages + structured_data = { + "@context": "https://schema.org", + "@type": "WebSite", + "url": request.build_absolute_uri('/'), + "potentialAction": { + "@type": "SearchAction", + "target": f"{request.build_absolute_uri('/search/')}?q={{search_term_string}}", + "query-input": "required name=search_term_string" + } + } + return { + "title": f"{blog_setting.site_name} | {blog_setting.site_description}", + "description": blog_setting.site_description, + "keywords": blog_setting.site_keywords, + "meta_tags": "", + "json_ld": structured_data + } + + def dispatch_seo_generation(self, metas, context): + request = context.get('request') + if not request: + return metas + + view_name = request.resolver_match.view_name + blog_setting = get_blog_setting() + + seo_data = None + if view_name == 'blog:detailbyid': + seo_data = self._get_article_seo_data(context, request, blog_setting) + elif view_name == 'blog:category_detail': + seo_data = self._get_category_seo_data(context, request, blog_setting) + + if not seo_data: + seo_data = self._get_default_seo_data(context, request, blog_setting) + + json_ld_script = f'' + + return f""" + {seo_data.get("title", "")} + + + {seo_data.get("meta_tags", "")} + {json_ld_script} + """ + +plugin = SeoOptimizerPlugin() diff --git a/plugins/view_count/__init__.py b/plugins/view_count/__init__.py new file mode 100644 index 0000000..8804fdf --- /dev/null +++ b/plugins/view_count/__init__.py @@ -0,0 +1 @@ +# This file makes this a Python package \ No newline at end of file diff --git a/plugins/view_count/plugin.py b/plugins/view_count/plugin.py new file mode 100644 index 0000000..15e9d94 --- /dev/null +++ b/plugins/view_count/plugin.py @@ -0,0 +1,18 @@ +from djangoblog.plugin_manage.base_plugin import BasePlugin +from djangoblog.plugin_manage import hooks + + +class ViewCountPlugin(BasePlugin): + PLUGIN_NAME = '文章浏览次数统计' + PLUGIN_DESCRIPTION = '统计文章的浏览次数' + PLUGIN_VERSION = '0.1.0' + PLUGIN_AUTHOR = 'liangliangyy' + + def register_hooks(self): + hooks.register('after_article_body_get', self.record_view) + + def record_view(self, article, *args, **kwargs): + article.viewed() + + +plugin = ViewCountPlugin() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..9dc5c935191f166db408850beb747475a262f65f GIT binary patch literal 2554 zcmZ{mOK)0H41~|RQhy3jxa83;x~aOVRHt-$MBCMc>m$SHk)3NsCx724O z&svob%XMU|V{iQC@?R zZ~0G!W+z_|B@^!EYb0|a8|zFJJ(1fNe%^|{En8uk>3b5kw*sb!x=F1+XweA^2Zpom&^VXcC#kB7{YUtyk1AW8lRCsH7kc&9|2FJZDW6fPxwcK<4UuCUBdsXLVs`_5F zp~0oR=sQS>?<%PjW*zBU@cbYY3-!J}L^}_3Y27N;PkG)pk*uJsc&?t#R3o*J(X1SA zka;NaQGO#GYHJxbBbSkJp-k9@@&PlNs$w3EcPR@sF|TltTB6Tpl&WX?P!AFM`gAq# ziDP5!b%x?N`7!_PG~o%JQRKX9Y6p=$>EBXOM*7a}6;HOi-71ev8|^_li^@^eSj@w__0A3aLAaD3lW$cY-+ejf+0D0n;c*g?m`=Y9 z#D{NVKaQOf&bHqN|K6p!G41^vmi8TR=TIe^a2}m??@)Ypmc4|+%#Zt&bBpa!Y_Lna z95ZK`d!>na86B&$`)xt#Oe-&k^ISIS%h_8C0ec(O{{Ln{w6Q!`KVv#@hd&K=)9UJoM~W6el-zM7!{x**T=1X z^wa1z+L2b5chAc%ZKb?k2fY03=7b3E0}!J+D^ z`Om~yc~RJ~yuIGH-QLq%`|ZTuPLXcJX{%xE{f6^yk|#Rdx2k=` SS`X?#O)JeKo3nk{t@?jbHFwMa literal 0 HcmV?d00001 diff --git a/servermanager/MemcacheStorage.py b/servermanager/MemcacheStorage.py new file mode 100644 index 0000000..38a7990 --- /dev/null +++ b/servermanager/MemcacheStorage.py @@ -0,0 +1,32 @@ +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) diff --git a/servermanager/__init__.py b/servermanager/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/servermanager/admin.py b/servermanager/admin.py new file mode 100644 index 0000000..f26f4f6 --- /dev/null +++ b/servermanager/admin.py @@ -0,0 +1,19 @@ +from django.contrib import admin +# Register your models here. + + +class CommandsAdmin(admin.ModelAdmin): + list_display = ('title', 'command', 'describe') + + +class EmailSendLogAdmin(admin.ModelAdmin): + list_display = ('title', 'emailto', 'send_result', 'creation_time') + readonly_fields = ( + 'title', + 'emailto', + 'send_result', + 'creation_time', + 'content') + + def has_add_permission(self, request): + return False diff --git a/servermanager/api/__init__.py b/servermanager/api/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/servermanager/api/__init__.py @@ -0,0 +1 @@ + diff --git a/servermanager/api/blogapi.py b/servermanager/api/blogapi.py new file mode 100644 index 0000000..8a4d6ac --- /dev/null +++ b/servermanager/api/blogapi.py @@ -0,0 +1,27 @@ +from haystack.query import SearchQuerySet + +from blog.models import Article, Category + + +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__] diff --git a/servermanager/api/commonapi.py b/servermanager/api/commonapi.py new file mode 100644 index 0000000..83ad9ff --- /dev/null +++ b/servermanager/api/commonapi.py @@ -0,0 +1,64 @@ +import logging +import os + +import openai + +from servermanager.models import commands + +logger = logging.getLogger(__name__) + +openai.api_key = os.environ.get('OPENAI_API_KEY') +if os.environ.get('HTTP_PROXY'): + openai.proxy = os.environ.get('HTTP_PROXY') + + +class ChatGPT: + + @staticmethod + def chat(prompt): + try: + completion = openai.ChatCompletion.create(model="gpt-3.5-turbo", + messages=[{"role": "user", "content": prompt}]) + return completion.choices[0].message.content + except Exception as e: + logger.error(e) + return "服务器出错了" + + +class CommandHandler: + def __init__(self): + self.commands = commands.objects.all() + + def run(self, title): + """ + 运行命令 + :param title: 命令 + :return: 返回命令执行结果 + """ + 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: + res = os.popen(cmd).read() + return res + except BaseException: + return '命令执行出错!' + + def get_help(self): + rsp = '' + for cmd in self.commands: + rsp += '{c}:{d}\n'.format(c=cmd.title, d=cmd.describe) + return rsp + + +if __name__ == '__main__': + chatbot = ChatGPT() + prompt = "写一篇1000字关于AI的论文" + print(chatbot.chat(prompt)) diff --git a/servermanager/apps.py b/servermanager/apps.py new file mode 100644 index 0000000..03cc38d --- /dev/null +++ b/servermanager/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ServermanagerConfig(AppConfig): + name = 'servermanager' diff --git a/servermanager/migrations/0001_initial.py b/servermanager/migrations/0001_initial.py new file mode 100644 index 0000000..bbdbf77 --- /dev/null +++ b/servermanager/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='commands', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=300, verbose_name='命令标题')), + ('command', models.CharField(max_length=2000, verbose_name='命令')), + ('describe', models.CharField(max_length=300, verbose_name='命令描述')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '命令', + 'verbose_name_plural': '命令', + }, + ), + migrations.CreateModel( + name='EmailSendLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('emailto', models.CharField(max_length=300, verbose_name='收件人')), + ('title', models.CharField(max_length=2000, verbose_name='邮件标题')), + ('content', models.TextField(verbose_name='邮件内容')), + ('send_result', models.BooleanField(default=False, verbose_name='结果')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ], + options={ + 'verbose_name': '邮件发送log', + 'verbose_name_plural': '邮件发送log', + 'ordering': ['-created_time'], + }, + ), + ] diff --git a/servermanager/migrations/0002_alter_emailsendlog_options_and_more.py b/servermanager/migrations/0002_alter_emailsendlog_options_and_more.py new file mode 100644 index 0000000..4858857 --- /dev/null +++ b/servermanager/migrations/0002_alter_emailsendlog_options_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.5 on 2023-09-06 13:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('servermanager', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='emailsendlog', + options={'ordering': ['-creation_time'], 'verbose_name': '邮件发送log', 'verbose_name_plural': '邮件发送log'}, + ), + migrations.RenameField( + model_name='commands', + old_name='created_time', + new_name='creation_time', + ), + migrations.RenameField( + model_name='commands', + old_name='last_mod_time', + new_name='last_modify_time', + ), + migrations.RenameField( + model_name='emailsendlog', + old_name='created_time', + new_name='creation_time', + ), + ] diff --git a/servermanager/migrations/__init__.py b/servermanager/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/servermanager/models.py b/servermanager/models.py new file mode 100644 index 0000000..4326c65 --- /dev/null +++ b/servermanager/models.py @@ -0,0 +1,33 @@ +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) + creation_time = models.DateTimeField('创建时间', auto_now_add=True) + last_modify_time = models.DateTimeField('修改时间', auto_now=True) + + def __str__(self): + return self.title + + class Meta: + verbose_name = '命令' + verbose_name_plural = verbose_name + + +class EmailSendLog(models.Model): + emailto = models.CharField('收件人', max_length=300) + title = models.CharField('邮件标题', max_length=2000) + content = models.TextField('邮件内容') + send_result = models.BooleanField('结果', default=False) + creation_time = models.DateTimeField('创建时间', auto_now_add=True) + + def __str__(self): + return self.title + + class Meta: + verbose_name = '邮件发送log' + verbose_name_plural = verbose_name + ordering = ['-creation_time'] diff --git a/servermanager/robot.py b/servermanager/robot.py new file mode 100644 index 0000000..7b45736 --- /dev/null +++ b/servermanager/robot.py @@ -0,0 +1,187 @@ +import logging +import os +import re + +import jsonpickle +from django.conf import settings +from werobot import WeRoBot +from werobot.replies import ArticlesReply, Article +from werobot.session.filestorage import FileStorage + +from djangoblog.utils import get_sha256 +from servermanager.api.blogapi import BlogApi +from servermanager.api.commonapi import ChatGPT, CommandHandler +from .MemcacheStorage import MemcacheStorage + +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 +else: + if os.path.exists(os.path.join(settings.BASE_DIR, 'werobot_session')): + os.remove(os.path.join(settings.BASE_DIR, 'werobot_session')) + robot.config['SESSION_STORAGE'] = FileStorage(filename='werobot_session') + +blogapi = BlogApi() +cmd_handler = CommandHandler() +logger = logging.getLogger(__name__) + + +def convert_to_article_reply(articles, message): + reply = ArticlesReply(message=message) + from blog.templatetags.blog_tags import truncatechars_content + 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_article_reply(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_article_reply(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(r'^weather\:.*$', re.I)) +def weather(message, session): + return "建设中..." + + +@robot.filter(re.compile(r'^idcard\:.*$', re.I)) +def idcard(message, session): + return "建设中..." + + +@robot.handler +def echo(message, session): + handler = MessageHandler(message, session) + return handler.handler() + + +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 Exception as e: + 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 save_session(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.save_session() + return "退出成功" + if info.upper() == 'ADMIN': + self.userinfo.isAdmin = True + self.save_session() + return "输入管理员密码" + if self.userinfo.isAdmin and not self.userinfo.isPasswordSet: + passwd = settings.WXADMIN + if settings.TESTING: + passwd = '123' + if passwd.upper() == get_sha256(get_sha256(info)).upper(): + self.userinfo.isPasswordSet = True + self.save_session() + return "验证通过,请输入命令或者要执行的命令代码:输入helpme获得帮助" + else: + if self.userinfo.Count >= 3: + self.userinfo = WxUserInfo() + self.save_session() + return "超过验证次数" + self.userinfo.Count += 1 + self.save_session() + return "验证失败,请重新输入管理员密码:" + if self.userinfo.isAdmin and self.userinfo.isPasswordSet: + if self.userinfo.Command != '' and info.upper() == 'Y': + return cmd_handler.run(self.userinfo.Command) + else: + if info.upper() == 'HELPME': + return cmd_handler.get_help() + self.userinfo.Command = info + self.save_session() + return "确认执行: " + info + " 命令?" + + return ChatGPT.chat(info) + + +class WxUserInfo(): + def __init__(self): + self.isAdmin = False + self.isPasswordSet = False + self.Count = 0 + self.Command = '' diff --git a/servermanager/tests.py b/servermanager/tests.py new file mode 100644 index 0000000..22a6689 --- /dev/null +++ b/servermanager/tests.py @@ -0,0 +1,79 @@ +from django.test import Client, RequestFactory, TestCase +from django.utils import timezone +from werobot.messages.messages import TextMessage + +from accounts.models import BlogUser +from blog.models import Category, Article +from servermanager.api.commonapi import ChatGPT +from .models import commands +from .robot import MessageHandler, CommandHandler +from .robot import search, category, recents + + +# Create your tests here. +class ServerManagerTest(TestCase): + def setUp(self): + self.client = Client() + self.factory = RequestFactory() + + def test_chat_gpt(self): + content = ChatGPT.chat("你好") + self.assertIsNotNone(content) + + def test_validate_comment(self): + 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.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 = "nice" + rsp = search(s, None) + 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, {}) + + # msghandler.userinfo.isPasswordSet = True + # msghandler.userinfo.isAdmin = True + msghandler.handler() + s.content = 'y' + msghandler.handler() + s.content = 'idcard:12321233' + msghandler.handler() + s.content = 'weather:上海' + msghandler.handler() + s.content = 'admin' + msghandler.handler() + s.content = '123' + msghandler.handler() + + s.content = 'exit' + msghandler.handler() diff --git a/servermanager/urls.py b/servermanager/urls.py new file mode 100644 index 0000000..8d134d2 --- /dev/null +++ b/servermanager/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from werobot.contrib.django import make_view + +from .robot import robot + +app_name = "servermanager" +urlpatterns = [ + path(r'robot', make_view(robot)), + +] diff --git a/servermanager/views.py b/servermanager/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/servermanager/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/templates/account/forget_password.html b/templates/account/forget_password.html new file mode 100644 index 0000000..3384531 --- /dev/null +++ b/templates/account/forget_password.html @@ -0,0 +1,30 @@ +{% extends 'share_layout/base_account.html' %} +{% load i18n %} +{% load static %} +{% block content %} +
+ + + + + +

+ Home Page + | + login page +

+ +
+{% endblock %} \ No newline at end of file diff --git a/templates/account/login.html b/templates/account/login.html new file mode 100644 index 0000000..cff8d33 --- /dev/null +++ b/templates/account/login.html @@ -0,0 +1,46 @@ +{% extends 'share_layout/base_account.html' %} +{% load static %} +{% load i18n %} +{% block content %} +
+ + + + + +

+ + {% trans 'Create Account' %} + + | + Home Page + | + + {% trans 'Forget Password' %} + +

+ +
+{% endblock %} \ No newline at end of file diff --git a/templates/account/registration_form.html b/templates/account/registration_form.html new file mode 100644 index 0000000..65e7549 --- /dev/null +++ b/templates/account/registration_form.html @@ -0,0 +1,29 @@ +{% extends 'share_layout/base_account.html' %} +{% load static %} +{% block content %} +
+ + + + + +

+ Sign In +

+ +
+{% endblock %} \ No newline at end of file diff --git a/templates/account/result.html b/templates/account/result.html new file mode 100644 index 0000000..23c9094 --- /dev/null +++ b/templates/account/result.html @@ -0,0 +1,27 @@ +{% extends 'share_layout/base.html' %} +{% load i18n %} +{% block header %} + {{ title }} +{% endblock %} +{% block content %} +
+ +
+{% endblock %} \ No newline at end of file diff --git a/templates/blog/article_archives.html b/templates/blog/article_archives.html new file mode 100644 index 0000000..959319e --- /dev/null +++ b/templates/blog/article_archives.html @@ -0,0 +1,60 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} +{% load cache %} +{% load i18n %} +{% block header %} + + {% trans 'article archive' %} | {{ SITE_DESCRIPTION }} + + + + + + + + + +{% endblock %} +{% block content %} +
+
+ +
+ +

{% trans 'article archive' %}

+
+ +
+ + {% regroup article_list by pub_time.year as year_post_group %} +
    + {% for year in year_post_group %} +
  • {{ year.grouper }} {% trans 'year' %} + {% regroup year.list by pub_time.month as month_post_group %} +
      + {% for month in month_post_group %} +
    • {{ month.grouper }} {% trans 'month' %} + +
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+ +{% endblock %} + + +{% block sidebar %} + {% load_sidebar user 'i' %} +{% endblock %} + + diff --git a/templates/blog/article_detail.html b/templates/blog/article_detail.html new file mode 100644 index 0000000..a74a0db --- /dev/null +++ b/templates/blog/article_detail.html @@ -0,0 +1,52 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} + +{% block header %} +{% endblock %} +{% block content %} +
+
+ {% load_article_detail article False user %} + + {% if article.type == 'a' %} + + {% endif %} + +
+ {% if article.comment_status == "o" and OPEN_SITE_COMMENT %} + + + {% include 'comments/tags/comment_list.html' %} + {% if user.is_authenticated %} + {% include 'comments/tags/post_comment.html' %} + {% else %} +
+

您还没有登录,请您登录后发表评论。 +

+ + {% load oauth_tags %} + {% load_oauth_applications request %} + +
+ {% endif %} + {% endif %} +
+ +{% endblock %} + +{% block sidebar %} + {% load_sidebar user "p" %} +{% endblock %} \ No newline at end of file diff --git a/templates/blog/article_index.html b/templates/blog/article_index.html new file mode 100644 index 0000000..0ee6150 --- /dev/null +++ b/templates/blog/article_index.html @@ -0,0 +1,42 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} +{% load cache %} +{% block header %} + {% if tag_name %} + {{ page_type }}:{{ tag_name }} | {{ SITE_DESCRIPTION }} + {% comment %}{% endcomment %} + {% else %} + {{ SITE_NAME }} | {{ SITE_DESCRIPTION }} + {% endif %} + + + + + + + +{% endblock %} +{% block content %} +
+
+ {% if page_type and tag_name %} +
+ +

{{ page_type }}:{{ tag_name }}

+
+ {% endif %} + + {% for article in article_list %} + {% load_article_detail article True user %} + {% endfor %} + {% if is_paginated %} + {% load_pagination_info page_obj page_type tag_name %} + + {% endif %} +
+
+ +{% endblock %} +{% block sidebar %} + {% load_sidebar user linktype %} +{% endblock %} \ No newline at end of file diff --git a/templates/blog/error_page.html b/templates/blog/error_page.html new file mode 100644 index 0000000..d41cfb6 --- /dev/null +++ b/templates/blog/error_page.html @@ -0,0 +1,45 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} +{% load cache %} +{% block header %} + {% if tag_name %} + {% if statuscode == '404' %} + 404 NotFound + {% elif statuscode == '403' %} + Permission Denied + {% elif statuscode == '500' %} + 500 Error + {% else %} + + {% endif %} + {% comment %}{% endcomment %} + {% else %} + {{ SITE_NAME }} | {{ SITE_DESCRIPTION }} + {% endif %} + + + + + + + +{% endblock %} +{% block content %} +
+
+ +
+

{{ message }}

+
+ +
+
+ +{% endblock %} + + +{% block sidebar %} + {% load_sidebar user 'i' %} +{% endblock %} + + diff --git a/templates/blog/links_list.html b/templates/blog/links_list.html new file mode 100644 index 0000000..ccecbea --- /dev/null +++ b/templates/blog/links_list.html @@ -0,0 +1,44 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} +{% load cache %} +{% block header %} + + 友情链接 | {{ SITE_DESCRIPTION }} + + + + + + + + + +{% endblock %} +{% block content %} +
+
+ +
+ +

友情链接

+
+ +
+ +
+
+
+ +{% endblock %} + + +{% block sidebar %} + {% load_sidebar user 'i' %} +{% endblock %} + + diff --git a/templates/blog/tags/article_info.html b/templates/blog/tags/article_info.html new file mode 100644 index 0000000..3deec44 --- /dev/null +++ b/templates/blog/tags/article_info.html @@ -0,0 +1,74 @@ +{% load blog_tags %} +{% load cache %} +{% load i18n %} +
+
+ +

+ {% if isindex %} + {% if article.article_order > 0 %} + 【{% trans 'pin to top' %}】{{ article.title }} + {% else %} + {{ article.title }} + {% endif %} + + {% else %} + {{ article.title }} + {% endif %} +

+ +
+ {% if article.type == 'a' %} + {% if not isindex %} + {% cache 36000 breadcrumb article.pk %} + {% load_breadcrumb article %} + {% endcache %} + {% endif %} + {% endif %} +
+ +
+ {% if isindex %} + {{ article.body|custom_markdown|escape|truncatechars_content }} +

Read more

+ {% else %} + + {% if article.show_toc %} + {% get_markdown_toc article.body as toc %} + {% trans 'toc' %}: + {{ toc|safe }} + +
+ {% endif %} +
+ + {{ article.body|custom_markdown|escape }} + +
+ {% endif %} + +
+ + {% load_article_metas article user %} + +
\ No newline at end of file diff --git a/templates/blog/tags/article_meta_info.html b/templates/blog/tags/article_meta_info.html new file mode 100644 index 0000000..cb6111c --- /dev/null +++ b/templates/blog/tags/article_meta_info.html @@ -0,0 +1,59 @@ +{% load i18n %} +{% load blog_tags %} + + + + + diff --git a/templates/blog/tags/article_pagination.html b/templates/blog/tags/article_pagination.html new file mode 100644 index 0000000..95514ff --- /dev/null +++ b/templates/blog/tags/article_pagination.html @@ -0,0 +1,17 @@ +{% load i18n %} + \ No newline at end of file diff --git a/templates/blog/tags/article_tag_list.html b/templates/blog/tags/article_tag_list.html new file mode 100644 index 0000000..c8ba474 --- /dev/null +++ b/templates/blog/tags/article_tag_list.html @@ -0,0 +1,19 @@ +{% load i18n %} +{% if article_tags_list %} +
+
+ {% trans 'tags' %} +
+
+ + {% for url,count,tag,color in article_tags_list %} + + {{ tag.name }} + {{ count }} + + {% endfor %} + +
+
+{% endif %} diff --git a/templates/blog/tags/breadcrumb.html b/templates/blog/tags/breadcrumb.html new file mode 100644 index 0000000..67087d5 --- /dev/null +++ b/templates/blog/tags/breadcrumb.html @@ -0,0 +1,19 @@ + + diff --git a/templates/blog/tags/sidebar.html b/templates/blog/tags/sidebar.html new file mode 100644 index 0000000..f70544c --- /dev/null +++ b/templates/blog/tags/sidebar.html @@ -0,0 +1,136 @@ +{% load blog_tags %} +{% load i18n %} + diff --git a/templates/comments/tags/comment_item.html b/templates/comments/tags/comment_item.html new file mode 100644 index 0000000..ebb0388 --- /dev/null +++ b/templates/comments/tags/comment_item.html @@ -0,0 +1,34 @@ +{% load blog_tags %} +
  • +
    + + + +

    {{ comment_item.body|escape|comment_markdown }}

    + +
    + +
  • \ No newline at end of file diff --git a/templates/comments/tags/comment_item_tree.html b/templates/comments/tags/comment_item_tree.html new file mode 100644 index 0000000..a9decd1 --- /dev/null +++ b/templates/comments/tags/comment_item_tree.html @@ -0,0 +1,54 @@ +{% load blog_tags %} +
  • +
    + + + +

    + {% if comment_item.parent_comment %} +

    + {% endif %} +

    + +

    {{ comment_item.body|escape|comment_markdown }}

    + + +
    + +
  • +{% query article_comments parent_comment=comment_item as cc_comments %} +{% for cc in cc_comments %} + {% with comment_item=cc template_name="comments/tags/comment_item_tree.html" %} + {% if depth >= 1 %} + {% include template_name %} + {% else %} + {% with depth=depth|add:1 %} + {% include template_name %} + {% endwith %} + {% endif %} + {% endwith %} +{% endfor %} \ No newline at end of file diff --git a/templates/comments/tags/comment_list.html b/templates/comments/tags/comment_list.html new file mode 100644 index 0000000..4092161 --- /dev/null +++ b/templates/comments/tags/comment_list.html @@ -0,0 +1,45 @@ + +
    + {% load blog_tags %} + {% load comments_tags %} + {% load cache %} + + + {% if article_comments %} +
    +
      + {# {% query article_comments parent_comment=None as parent_comments %}#} + {% for comment_item in p_comments %} + + {% with 0 as depth %} + {% include "comments/tags/comment_item_tree.html" %} + {% endwith %} + {% endfor %} + +
    + +
    +
    + {% endif %} +
    + +
    \ No newline at end of file diff --git a/templates/comments/tags/post_comment.html b/templates/comments/tags/post_comment.html new file mode 100644 index 0000000..3ae5a27 --- /dev/null +++ b/templates/comments/tags/post_comment.html @@ -0,0 +1,33 @@ +
    + +
    +

    发表评论 + +

    +
    {% csrf_token %} +

    + {{ form.body.label_tag }} + + {{ form.body }} + {{ form.body.errors }} +

    + {{ form.parent_comment_id }} +
    + {% if COMMENT_NEED_REVIEW %} + 支持markdown,评论经审核后才会显示。 + {% else %} + 支持markdown。 + {% endif %} + + +
    +
    +
    + +
    + + diff --git a/templates/oauth/bindsuccess.html b/templates/oauth/bindsuccess.html new file mode 100644 index 0000000..4bee77c --- /dev/null +++ b/templates/oauth/bindsuccess.html @@ -0,0 +1,22 @@ +{% extends 'share_layout/base.html' %} +{% block header %} + {{ title }} +{% endblock %} +{% block content %} +
    +
    + +
    + +

    {{ content }}

    +
    +
    +
    + + 登录 + | + 回到首页 +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/templates/oauth/oauth_applications.html b/templates/oauth/oauth_applications.html new file mode 100644 index 0000000..a841ad2 --- /dev/null +++ b/templates/oauth/oauth_applications.html @@ -0,0 +1,13 @@ +{% load i18n %} + diff --git a/templates/oauth/require_email.html b/templates/oauth/require_email.html new file mode 100644 index 0000000..3adef12 --- /dev/null +++ b/templates/oauth/require_email.html @@ -0,0 +1,46 @@ +{% extends 'share_layout/base_account.html' %} + +{% load static %} +{% block content %} +
    + + + + + +

    + 登录 +

    + +
    +{% endblock %} \ No newline at end of file diff --git a/templates/owntracks/show_log_dates.html b/templates/owntracks/show_log_dates.html new file mode 100644 index 0000000..7dbba21 --- /dev/null +++ b/templates/owntracks/show_log_dates.html @@ -0,0 +1,17 @@ + + + + + 记录日期 + + + +
      + {% for date in results %} +
    • + {{ date }} +
    • + {% endfor %} +
    + + \ No newline at end of file diff --git a/templates/owntracks/show_maps.html b/templates/owntracks/show_maps.html new file mode 100644 index 0000000..3aeda36 --- /dev/null +++ b/templates/owntracks/show_maps.html @@ -0,0 +1,135 @@ + + + + + + + 运动轨迹 + + + +
    + + + + + + + + \ No newline at end of file diff --git a/templates/search/indexes/blog/article_text.txt b/templates/search/indexes/blog/article_text.txt new file mode 100644 index 0000000..4f9ca76 --- /dev/null +++ b/templates/search/indexes/blog/article_text.txt @@ -0,0 +1,3 @@ +{{ object.title }} +{{ object.author.username }} +{{ object.body }} \ No newline at end of file diff --git a/templates/search/search.html b/templates/search/search.html new file mode 100644 index 0000000..1404c60 --- /dev/null +++ b/templates/search/search.html @@ -0,0 +1,66 @@ +{% extends 'share_layout/base.html' %} +{% load blog_tags %} +{% block header %} + {{ SITE_NAME }} | {{ SITE_DESCRIPTION }} + + + + + + + +{% endblock %} +{% block content %} +
    +
    + {% if query %} +
    + {% if suggestion %} +

    + 已显示 “{{ suggestion }}” 的搜索结果。   + 仍然搜索:{{ query }}
    +

    + {% else %} +

    + 搜索:{{ query }}    +

    + {% endif %} +
    + {% endif %} + {% if query and page.object_list %} + {% for article in page.object_list %} + {% load_article_detail article.object True user %} + {% endfor %} + {% if page.has_previous or page.has_next %} + + + {% endif %} + {% else %} +
    + +

    哎呀,关键字:{{ query }}没有找到结果,要不换个词再试试?

    +
    + {% endif %} +
    +
    +{% endblock %} + + +{% block sidebar %} + {% load_sidebar request.user 'i' %} +{% endblock %} + + diff --git a/templates/share_layout/adsense.html b/templates/share_layout/adsense.html new file mode 100644 index 0000000..8f99c55 --- /dev/null +++ b/templates/share_layout/adsense.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/templates/share_layout/base.html b/templates/share_layout/base.html new file mode 100644 index 0000000..75d0df5 --- /dev/null +++ b/templates/share_layout/base.html @@ -0,0 +1,123 @@ +{% load static %} +{% load cache %} +{% load i18n %} +{% load compress %} + + + + + + + + + + {% block header %} + {% block title %}{{ SITE_NAME }}{% endblock %} + + + {% endblock %} + {% load blog_tags %} + {% head_meta %} + + + + + + + + + + + {% compress css %} + + + + {% comment %}{% endcomment %} + + + + {% block compress_css %} + {% endblock %} + {% endcompress %} + {% if GLOBAL_HEADER %} + {{ GLOBAL_HEADER|safe }} + {% endif %} + + + +
    + +
    + + {% block content %} + {% endblock %} + + + {% block sidebar %} + {% endblock %} + + +
    + {% include 'share_layout/footer.html' %} +
    + + +
    + + {% compress js %} + + + + + + {% block compress_js %} + {% endblock %} + {% endcompress %} + {% block footer %} + {% endblock %} +
    + diff --git a/templates/share_layout/base_account.html b/templates/share_layout/base_account.html new file mode 100644 index 0000000..c00d842 --- /dev/null +++ b/templates/share_layout/base_account.html @@ -0,0 +1,47 @@ + + + + {% load static %} + + + + + + + + + {{ SITE_NAME }} | {{ SITE_DESCRIPTION }} + + {% load compress %} + {% compress css %} + + + + + + + + + + {% endcompress %} + {% compress js %} + + + {% endcompress %} + + + + + +{% block content %} +{% endblock %} + + + + + + + \ No newline at end of file diff --git a/templates/share_layout/footer.html b/templates/share_layout/footer.html new file mode 100644 index 0000000..cd86a29 --- /dev/null +++ b/templates/share_layout/footer.html @@ -0,0 +1,56 @@ + + + diff --git a/templates/share_layout/nav.html b/templates/share_layout/nav.html new file mode 100644 index 0000000..24d4da6 --- /dev/null +++ b/templates/share_layout/nav.html @@ -0,0 +1,30 @@ +{% load i18n %} + + \ No newline at end of file diff --git a/templates/share_layout/nav_node.html b/templates/share_layout/nav_node.html new file mode 100644 index 0000000..c266880 --- /dev/null +++ b/templates/share_layout/nav_node.html @@ -0,0 +1,19 @@ + + + From fd754d9f87be2eaf786f16ea2384ac4a05a19302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=98=95=E5=84=92?= Date: Wed, 24 Sep 2025 13:03:16 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test.txt/{1.txt => 3.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test.txt/{1.txt => 3.txt} (100%) diff --git a/test.txt/1.txt b/test.txt/3.txt similarity index 100% rename from test.txt/1.txt rename to test.txt/3.txt From 076fef024cf97e3c087024fa5ecb8166ad6cc697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=98=95=E5=84=92?= Date: Wed, 24 Sep 2025 13:09:27 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test.txt/{3.txt => 0.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test.txt/{3.txt => 0.txt} (100%) diff --git a/test.txt/3.txt b/test.txt/0.txt similarity index 100% rename from test.txt/3.txt rename to test.txt/0.txt From 8623ec3caf53b0b884d5fb6c6702b6a9f1e25e06 Mon Sep 17 00:00:00 2001 From: guqi Date: Wed, 24 Sep 2025 16:28:14 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20gq=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test1.txt diff --git a/test1.txt b/test1.txt new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/test1.txt @@ -0,0 +1 @@ +test \ No newline at end of file From 6dac1cc00e14d431defc040e0f6f2db47edae456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E7=91=9E=E8=90=8D?= <1909818175@qq.com> Date: Wed, 24 Sep 2025 20:14:39 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8Bzrp=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1zrp.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 1zrp.txt diff --git a/1zrp.txt b/1zrp.txt new file mode 100644 index 0000000..e69de29 From 5a2f7c5bf569326d0e98bd74f5d926e961d42974 Mon Sep 17 00:00:00 2001 From: guqi Date: Thu, 9 Oct 2025 13:12:52 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20gq=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 关系模型图/@startuml test2.wsd | 99 +++++++++++++++++++++ 关系模型图/@startuml test3.wsd | 129 ++++++++++++++++++++++++++++ 关系模型图/test2.png | Bin 0 -> 85437 bytes 关系模型图/test3.png | Bin 0 -> 126801 bytes 4 files changed, 228 insertions(+) create mode 100644 关系模型图/@startuml test2.wsd create mode 100644 关系模型图/@startuml test3.wsd create mode 100644 关系模型图/test2.png create mode 100644 关系模型图/test3.png diff --git a/关系模型图/@startuml test2.wsd b/关系模型图/@startuml test2.wsd new file mode 100644 index 0000000..254b487 --- /dev/null +++ b/关系模型图/@startuml test2.wsd @@ -0,0 +1,99 @@ +@startuml test2 +'==================== ȫʽ˵ ==================== +' ʾأȾ֧壩 +skinparam defaultFontName "Microsoft YaHei" +skinparam package { + BackgroundColor #F8F9FA + BorderColor #2C3E50 + FontSize 11 +} +skinparam arrow { + Color #34495E +} +skinparam generalization { + LineColor #E74C3C +} +skinparam dependency { + LineColor #3498DB + LineStyle dashed +} + +'==================== ==================== +package "DjangoBlog.Templates" { + package "Base Templates" { + file "base.html" + } + + package "Business Templates" { + package "Auth Templates" { + file "login.html" + file "register.html" + } + package "Blog Templates" { + file "index.html" + file "post_detail.html" + file "post_edit.html" + file "archive.html" + } + package "User Templates" { + file "profile.html" + } + package "Admin Templates" { + file "dashboard.html" + } + } + + package "Component Templates" { + package "Blog Components" { + file "post_card.html" + file "category_nav.html" + file "comment_list.html" + file "post_toolbar.html" + file "rich_editor.html" + file "cat_tag_select.html" + file "pagination.html" + } + } + + package "Template Tags" { + package "Blog Tags" { + file "blog_tags.py" + } + package "User Tags" { + file "user_tags.py" + } + package "Admin Tags" { + file "admin_tags.py" + } + } + + package "Django Built-in Tags" { + note right of "Django Built-in Tags" : ں {%for%} {%if%} {%static%} {%url%} {%block%} + } + +} + +'==================== ̳йϵextends ==================== +[Business Templates] --|> [Base Templates] : ̳ +[Auth Templates] --|> [Base Templates] : ̳ +[Blog Templates] --|> [Base Templates] : ̳ +[User Templates] --|> [Base Templates] : ̳ +[Admin Templates] --|> [Base Templates] : ̳ + +'==================== ϵinclude ==================== +[Blog Templates] ..> [Blog Components] : + +'==================== ϵԶ Tag ==================== +[Blog Components] ..> [Blog Tags] : +' ʾûعܵûǩ +' ü򻯷ʽ֣ʵʿɸݾԪϸ +' user ..> [User Tags] : +' ʾعܵùǩ +' admin ..> [Admin Tags] : + +'==================== Django ñǩ ==================== +[Base Templates] ..> [Django Built-in Tags] : +[Business Templates] ..> [Django Built-in Tags] : +[Component Templates] ..> [Django Built-in Tags] : + +@enduml \ No newline at end of file diff --git a/关系模型图/@startuml test3.wsd b/关系模型图/@startuml test3.wsd new file mode 100644 index 0000000..02d8e87 --- /dev/null +++ b/关系模型图/@startuml test3.wsd @@ -0,0 +1,129 @@ +@startuml test3 + +' ͼķΪ +left to right direction + +' ģ +class ģ { + + + + ײϢ + + ȫʽ/ű + + +} + +' ҵģ +class ¼ģ { + + û + + + + ¼ť + + + + ע +} + +class עģ { + + û + + + + + + ֤ģ + + עЭ鹴ѡ +} + +class ҳģ { + + Ƽֲ + + ർ + + б +} + +class ģ { + + Ϣչʾ + + Ϣչʾ + + +} + +class ±༭ģ { + + + + ı༭ + + /ǩѡ +} + +class ģ { + + չʾ + + ѷб + + ղб +} + +class 鵵ģ { + + ɸѡչʾ + + бҳ +} + +class ̨ҳģ { + + ͳƿƬ + + ڲ־ +} + +' ģ/ +class ¿Ƭģ { + + ± + + ·ͼ + + ժҪ + + ʱ/Ķ +} + +class ർģ { + + + + +} + +class бģ { + + + + Ϣ + + ʱ +} + +class ¹ģ { + + /ղ/ť + + С +} + +class ı༭ģ { + + ʽ + + ͼƬϴ + + +} + +class ǩѡģ { + + ѡ + + ǩѡ +} + +class ҳؼģ { + + һҳ/һҳť + + ҳת +} + +' --- ϵ --- + +' 1. ̳йϵҵģ̳Իģ +¼ģ -|> ģ +עģ -|> ģ +ҳģ -|> ģ +ģ -|> ģ +±༭ģ -|> ģ +ģ -|> ģ +鵵ģ -|> ģ +̨ҳģ -|> ģ + +' 2. ۺϹϵģģ/ +ҳģ *-- ¿Ƭģ : +ҳģ *-- ർģ : + +ģ *-- бģ : +ģ *-- ¹ģ : + +±༭ģ *-- ı༭ģ : +±༭ģ *-- ǩѡģ : + +鵵ģ *-- ҳؼģ : + +@enduml \ No newline at end of file diff --git a/关系模型图/test2.png b/关系模型图/test2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a34df7019c0f0ba497429ccd2af037994fbe5dc GIT binary patch literal 85437 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 z zrRv6GepobSg(!O14is@gKQ^Yf!Ld<)5+1*!3My*F4brCUSKGkrxg1V=eKrZPF zyI0%&HVhku+;R6!6VvZeQLu{l(fTR6TA75kXR3x6!%1ktjSnKZ#3n|4!~IWbu1G;; zK2Dv{R;oxxje`r3WoWiV8*)_fkVf-v){ZObk8m|QBV=4*XVf8GcfE2~9IpcSgTCCP z!7aOP0ED(i2LrNF_OGzvsM}g6!9h_`#TFO&(+v{AYIpAl8UFD0R4buF<_p)Fhu);# z{N2Zpy8=wm)Q3r;)B|TF$o>-w~@yn0Snchs0NaBpy(AmU&_VbhT&W^yPEv|r- zaszkFAQn70%8Gjl4!=w*<)9-&?YC|A7~1*}|4=-09F&h_l}Me^NA=^1b|CBZV3<;P zp(vcTLItcN*`YskEauJDSm43|S!j>M*V}5iIAiBVw8*FEWH@o@{=RD(vl9*t>HQsm zI;uwkA`RlTF=+`nXrBeRY=SacphWTfnWjh~6Rew36Ac7^jMK`j@>~Hg3iuNw44&jS z6)%ZJJXiQ{@LPf^7k|eOdoP!PJgDljpU1}fuJb9xNZpxx(3XQx-)4| z;>vV8s!x3C(GG!t+DM=?m6q~;)4Vn#|N2c(jo^8_ z+CyyNFN4Uey_ly0h+$)|%>7EcgFiq*pAKYw9Nq^sKylRbhR>C&f7B}d)1dW3EkYL@ zDt|}}QJET+Hbi*{Hg@pBi&d&b*_7vdbQC}5pSnN)%Z6j*@9EJbU!H04J~|JKw+N`p zWj#3m_cvdLp#SkTm%beAR)|EpJgq{_=Z|J?pd8LZW6w^n()``$C5&0+;&=L~lav_H z#9rfj@IS8=Owr6`cCud{9HD#Vcmq3qG4_8pi|&U&&*l@kLV#1U4=@G@p8fxa zSGRuZkOD0uV7y!6|MSA56a@aPlm3TQHqw{NDt$--D(fKGzc2&-=ij}u!IS|9NXFlV z`xNYaRxK(*wz9xBa{qswm5G4J$O?N)1-7U7!rI!}GM(1PXZ_WgD^bV`##IVGRC(iI zAr`yx?lq4DdQV*zL#mk-B@D0;PXO`#g`Wd);rBn4SiItk93+)k&e%|LRE5>uU)y1r zOg-^{_v74W(zKVnLR2zegojWcucP1Bbb5EWJCbuDhb(LqFg_6x5nk8RS65vQeP6$R z9mnfXKOta@x`XDlHq0F8Q^iJFg$xcxCBZ7(1MD_1UZXfLwAWlFv31k~9id6ToJhm@ z5A>QvAu8ovuFx4Y3S%6IfVQ#n*R4_9pDx8lQ9h_Z#;WZ1%Q0Y_Bq3x}um1fGBb=MC|9JjD zP>NIqCazG)SJ;nddk52;uMe)h#awfuI4q~f_rC-k8nZJh*y$HX-wiVWkOiBhE1A{Z z9_f8NlLn7WUv{c(keZx-*4!{Bzlk#!cdL^VEtV|5m|oj{9qp&Xt3)S5 zpTGhaV1hPjIlk@tMqxjD9qsGjFtg*S#!aWh8l`i7H{B$r0JD@Bq+L zLtmrPQy(uD>7nlXsV?S8uv`DfkjtNLI^1r>_zZTtNB_5I0tYh+9Bn~z1VA) zc^Wfu$=zHD_Ba1A%AWG4i#!a~n)F{c9Tt$-J#D`1Q7``(X@P zvUR>ujhA!k9+w43<<7bafG=y=uYsf2fW5C*hQg7DDBfWO1FwZ4#;|SrviA4Eu3!;X zfx-5NB@|FU*uEUB^88QCVTI25Q9A9`z+1()-)ggjbl>Mv@Y?EtU9eQqv1SU6Q~{VM zuEKs^#fBmFO0pmb6kt@1c@jsJzxl;19-}p+UsQY76!oF;r&|pDnaCoiGa>b>GOE(` z8z;Fpd@(COZ~gR6c!1?9lO#<|jg^8}eU`nxw6uZ2Q1_z=NFj#>K=+ug_&PyDN+6{h zUhnA0F3@f6abU}H66<98q!qkl^B=QX{#4nndl+durPqAf(LVjO9lGXUb80;6_0-Ia zq2jSlDS(u~ReYz85YGI_BlOI>E#R{}R8gHCqGq*4=kY$Gt#%Un{uevP5?%dID;6b; zQUxceLE{t-(DmvGD>4⋘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 Q+S_3h%L7IGe);Wx0XY=|?*IS* literal 0 HcmV?d00001 diff --git a/关系模型图/test3.png b/关系模型图/test3.png new file mode 100644 index 0000000000000000000000000000000000000000..1234e8d2c412c1f85884a9f9f954370929fefee8 GIT binary patch literal 126801 zcmb5V1ys~s+czqqfG8m--QA3oboWRjNW;+GAl)I|BVB@^AdQlWv@}R}cT30FaKHEa zJ>U7_tiy6GXAR8!>)O}#s~xVSApP_);o}Dn9z2zmkx+T?0HOZD1LRdyMDPv|6}$ud z$LK7n=?t^8e`jrC>ij_3#MZ>o(AmV8+~^&-xwEsq6CWF!y|tmOvx|*2E6mQuwXd5D zd_}W`nx^x=?>|5Q-{YRXqoJ)zs6p&Ir|2+SyhAQE3=IucDB!M17*r@oZNQ-kAqd7` z?mOm2qU3of8f6srf_wH;$V02=%NHgm>4KNb8tZTS5ItRU5<>g(G53*gx9o0fuMft5 zPYE{InGoz_unBiLWFatfuY{n^ajo?5O*RJ>*%YZHS!$PgJ<6kjH>@U;e0Bd(@89wL zI29#AAqM8}R;OFcfy*(Z`^5Bf#k}-81d{6I&xEyQ)~6o+dXIfp9-Mn2;4ZvDTQw|? z&cmZm8OblJlg?L>7xB+kAng9dB;1{3C}`2PMc{mvlZO_X?T)gf4)4uf#^AHFZ$6!u zNqRDk6=}a*%QZgE@gr_-S-I+oD%$jPaE>Z<5I@0tLtZ>~xoZ3acm$6eF4QCA`A@ufup^#4FZEVFAdY(iSfyDZ?ePZMmQO zLjSI}DEFN_Uub`TVzc5v8GJ%@XoA5bQKh<09UUSo7}c8>!k*eLmRTcl`i)cO;K@Vr zc4nLBJG>2(35vz3VwS{4zMryk>yUU3?WrOHpT>8>B}?~~R%;;gtho)s>>BI}UY!EU zWL)qYw31eN)~bl=b2GLmwePXT>P0GkCD{~D)fb2=MC}NA%C7LBw!h?*^gm+M@YKG_ zFvgwHDJu^Qf-R-v&KAL=k&9e^8xMAT`zmc1{KXc|dD28W91OMjXQGaO93v2x8n ztCP5j!!?-LRGWRQR3FQtsL+2Gva8X4HjZZdIEF5i;ff6T|&ezK7UeARgW$~TIM5@mZwHu>WtftRIP)3c)okO^t zS@g%${26`OrP^|Z?7`Mn3NQkt6XYke#^!*EY(}m ze{)Ps%C8d<^dO#1iuG0Onm45o&$5m9Ecdd_Et(yXV}TC$WhQ`>_x_V6@!xY`)0f31*3 z-+{w*EWW=<;@S0KYMNsLa%Pr|!6wQsndZ?Y5BgkN(Srwm4`d}o)!g;AGtiXOG@5SB z-l-oI=ruMp_?lSuq*3D}L@F!mJWxK7oL0ttu52%@Ch}HtTB%jJ!&_WZP2|M{HnNVr zXgE53_A?E&R+q3`x06@0tGBPS7Tg6I^Xu(+EY^=0inmU_ug%)l`Cfl-p408S?rKIx z^cTq{5ndp=fAPo=>Mue*@Z$gSU$UzOR5t!*KUDbY=CoO#W+3J4?Ckyf$2SSjQIQEP zQrdNzeXf6nV$%2vR8&@Ck_vSCegnr4+!=y@*7&;WdyUvAlG*p)@112F348nNT`gex z&I{{+b0IZ^R!ZTkk`JI&a;!!q#g%+oGZ$f*0fZo0RLMU1WDTDAS> zv&I!73E|!8()D!0zvgRLoNrtcTbJxun@XYBcFtCuO32M7Q3@ClvW%W^yDFT7%3~bK zyXpi%9wKJ2$c)GM0W0!Q>$fCod&f_j2joh;Flu0I`O3JOYLyw}0% z`ugb?MI-~(x!-}SkUI=i=T37Yxx91a%Se*6&eShqM_?uv?v zl8z=u!^HHh&!fO@$3=C{4J0~R`J7S{ea*F3uXb9?Y#1EzIifpnO;S>_=<&(+1P&Hf z?1vBG?F9w2P#zwhO2MtoO&P@(aEGZH8*3i>g_hunN;4QG6BD|($ML#<$N0D=8{5~{ zY1~nST$`W2Hc<-pXYlhlt@hNuNTzPEH8L_XH~-Yl^9AGn;`zQo(B(1TPEFBI?Hjmc z_7l&Y3STtqU#+q6xm{CR{t~MfJ(($C{$}eM?YgqEawSJoR8esVjtCEnjGQhr{FNgf z+H|%UF+V>Ks^V9gwW4`xPL96~f_yTwsA6e(aj|7zIxqZeiR?B^nvRZ6AXCVjkC}OU zCwk5-uT!M!xXxv(FHvG!8HF+Pc_KJ#%vgtL5^k1ItC1m#X z^>v!%bY=>AHoc>n`S%$O_f7bSkG|*&Y!Xc%?{J&-Hv3rs?r>h88&?u_HHohD}?ARu6R^F;*PdvCU}_EIi}OnCK~;xfDyo<9&`3GwI4 zScX3kGrr{K;~TP2o1-7Hh_kd;i2k6&C{laAMC`S%1WwPS2O6$>0muU@ZVl6M4a zCl4e~Pl{)0d5u=P@s!df2gjc!$vtD7b69H6F_ub3QKzAyS+MZ(5_s8LSI0LLx*W(T z8jWTlB_SbF?~GM|hC}=6)hjhMHJSJE={qsg2~C{)$H&`q&A#5=f*T)_k|Y@q78i}a zyxs1=MU9k3;aNo?^NIET?sqibf4j8CzWTFRr&RYG^S960VCXcTvPVZ-+f2hdoMHET z6l3Z(Yznm%c0y;_)c~up(zx$vXlTxb%SlWcghWKzDVIVMRpsR$1U*k;Da7UE!B8tJt8!G+;Gm%SrwwnR==aNdeZGBrHm}|>`g}O+ z2DiPZbm4XJRqd@>stKD=hk)BIF=^bB7C&oRd{WZPgoNRtp_V`Mss&KACr=V_+a)l@ z2L>L5Qf5FE6bigucc;JG%?YWkq_FB1fBDj??u*yVf=dx4jj4`@6~S7p`_xmYX|MwF$5ljjwvalqDr42jeB$wbz%Yu$I0) z+aG=i#+VFx!K6$ba_uo>G2tt}Q#v|2K>4JVs>=U+2cASc))0ClWZJHYe>8J?!{hAI z+N6r2aCvMY=0Bk+Rw-cUdDdb3Rj=cW;cI~=*-NL)?fjZX8rAL zZE;R?UBf>EQ7Y?cX@dWbmT2P<6Q`%8F;%a^;Ua=UUT6EMsf0C0!RUCJ!WS18yOY)E zytIxgyN^$g*7_CGUt!}64i3r)95~N5yhFhxJw812xHx8*Izst(bsT|Fp}?xpJ$7ZR z+nq(od#xJL?{lu-Oifp=h>;Z{RnxzEtvxe6&ACk=A+<3-FH*4ZrJ+Hl1|)`974Cer@)(}=l<7T zOLBBJcNxACk*=E#(Rep!g7VLpKYCe^|LU2po*pR<&eFodAV3KU8GH-a!{(y(Ayi8w z&;FUgeQ?BkSV9*B>HTNm|F175KSNIU=9=ZmW0seV?>`3KIX9Ng#=D=%>Q#Fbk$HJl)pWg^owYUd$jRZ#Z^K_9f5yhL_*^V|Q@QNEZa-C5R}Xyj zbjZH8^YHMH*J)MeeF{FWBek&h(|>SG5ky>EyqahA;_p_M_b*XUVy~yKuC5ZLL(^WG zJa&}2I0nCo-3CpkYdASMdALv!<F;nPj@#oLdk@yhHkxy(*X928z zFJbLZmfO5OQ_nPc6YZfKk_foli-f;t!8Jp7lFri7{P#bk9YD2I0|E55ucw+>zxrc)8Ig)H_Y^4r6lhrtM3JtD1 zgzp{;^YQW;W>}MrjDZE|Xm9_`ZI5*Ok+2aWVVnFsL|B-Nfo{8tRcw8-dTYEKcK$|I zEctzv8yNW19YG?7P)F_ggQbpPp1gmmjxQ0C(>Z6m&#&XV+jS(oh&{ZS&+B`01r8Ux zLDmB?>q{>hg2UP)4Ygw*Bqt_Le|IW$TI-`O3bLf4q#PHrH>tIq2}|+z@&Y(5AvV^p zFm@(SIwn)#UBGk#2XjtoDaK)jkoN^>?`Q8G(<)|Ko0+-oPV*W;hv-40z)!|7fi5RW zjxlbiLi2(@+=hT*A}5=4_WNeX zmB+M7qVn(4R^pL_z#&V&em(vBSI~Xmz{qHE3f&v?*+PDP{xpyX(D4qBa4l9l$b2I! z8tvwqz`Y2BSXo-CJm*1~{pOI@+$>z|<3sT9zC4`iVK@DZUpxAnze=IOrO-KUpMJ_1 zE76voJ`Gg=4%(rLz#XJxWM+=Eq89MI@!A|Iig>}YXvU5Odx3|SN2ll98itL<`m*=S z7iJUKY_sp&*|&%-fZ!k$DbK5uzx-zzG;npFYK+X-!E_Z*W>u zh==9=kmf4sgM()y$t_n9$HBPQt5arxpd#-oOlyG$%I=AL=*xnWOGxNbBB{coqa!Z0 zl|O&}>|;#jMynPou;@1l(9@%Ckn()iZ}u@p{8JYiD(&i86A^))2_E|ZF-~x$94uEs zn(PAC!Zb_ByT*D#OgmPCa!bH*8Py8v_$6I!1sfY%Sy{PCIN~4Z+6|9)?dZ-a`MWhX zT)3|R7MgcA0S7yKS;gV&+2Z&@#jF-@E-o&3$oIskqV(Fj@81^=_7{F}b_7A&eE-8r|z9FE9TVRxF^eOYjeNPlZ%daC0Z8dx>{;c8b`ZU7a5R zWWlCg^Ms2l{0!lndb{hrO2l9KPXoj25NqI5=3u&f#on2B(35)u<7E`E%} z#l$_57)Q1p(g?W zRTO^w=pbJ{Z=>Jnkt7ssQ%>^(`I(Bx;s_??-S`ZeAW;4B&nxzVw^a9U{qJ7qP-1|k*z(*yz^)D0vO#9Evp@&)W=CUKZoov6Yh!|*TG16k{#L5xI zUClp}%mPhf6yDq0J3Y`M9*SXN<%&b_pO-<~0SYT8 zNd-L;T|F<3ivk0Ya4lf4K;(pU4GB=heal@5G{Z#yaRP}|`~Vrda#2=O4};-U(0+V+ z3T_(T&dK^9RXnUOOE`-ZBbQj%$Ez!z#yTQA@;@J9S2PL#dWm~OW8+2%Wk!1XctCAY zQFvxkUp!byv9a@OYbehvc4%Mzd$IsfNF07T49XlBP-4Lpp&}sWu_g8#mwx%--zS2` z!ByZ#{(r3W|KlR~Kv?5Jv z5FIoaz_%g=y#H>hOGqHQP0-{tGw6tY+S`K`6}s@cW=%uiyG@rEEt&akK&B2=S$Vl(mZ_N;n`W7x4F$7y zjrE^mb>j>0@W8mqL!?Q8HEmcL|NF(eU^H(GeH{C$f4aXf^78C(Mc&ufS75fz<+JDM z?)3O7n7f9KHMv~Un zUmQuU&kkU$2NKb;k+NT((jm3}-J2tedH(!47)2qE0ok}(?!u|c|M-!jh+0ERtRsQ; zb?#?G6b$0*TkP5A{J+QlM?H>9#*Te+SW?ImdYVFk0+o|%89qC6H%>iHwH^5l)jEIC z388qMpMXXD3|gm!UkO+_9UY2=siEOQBmsvEKY<;b{oSE4HCz+zu>0G$S5@Q_5`FTk zK)6Ubu}1pu4q)m99x|Qwr}vSD{?e{bC~!MJbqfj#=E%Rq8z|>}_Uu_pOAEl1SlWtt=7}~GKm7hD=IrqT+kZR(9|xMjm-K`S`8Hl#bs$ql3n(`- zj!?u%D0Ot}=*&z;O)bK|SjMuMOjTuC(rhSS);gNks5J~ILi^XaBY*yYF=+>MDRx?d z`S`sYKYX0(6M*U|^z(By-yc=v;~zzFtpae~#o{|SH#~gwT6pPx4oLtMk^i^cQPyFp z5 zPq-RE)fSDbqobpj_px900v)DIFe>UF(9jF#^N$?*`O_cTpT+~`aZCn!#M`%T;}HDV zbiRS1ii?F+W;Mq8FF~bH5pzT?0z6h&cy4w!v&Y8LQme^}xBCj9i_x*M)7_c0Ps#RI zX9xP%n;K=$-&q1_X;;nv#A3L>ArF`6`M=bQg@t7~k}@D8L$`SGi4$0hLjkQgE4=k< zaX=#Q$Bln2W+?9Qdm1#EUN{8lyP1s*%jR`{KB%AsI>oYA-db?I{&S8kKO~}7v6+!Z!IsUIY{NFOM zVGl+NAorjp$Yz0xqmP*{iu~t8wmqSkWPKU@DUs~?@!ppwJ9EwYDv=5j7&fX`*Vh20 zb+cuYGcs;Qurv=<1MBXp0?Q_#Mep8y&zG4VPoQC8W?qj? zQKDd$ZR0WPBSwu70z~LCS298dJVQG$=1Vop16aRVPrQ6-?x3nV3_64iKLQ&9Y*Dg{ zDO;Te#-u6_hTST?bKQJxB z-u0*RBJB*F09DQ#=sYrxIotdD_G%OEYhZTeNkz%2KUsr-?oi|+umoreA3r}J9Y6YF znd656(ajQg=Xi5+3zeyskhe9p@NYU<2@V)Cg1vHBQlc>%#sEa5PS>O3Q!c zOIjHVYZ){i`?wlrDE-pCyj&J$(336U$0UD9q>zsN;ly9DjI@ zhZic@$$1fj4?&y(9ki2#i+lpC*%%W37hSYz@1KQ1K8_B~AFP6L0M%C``M1Apa=H$N zPOBGml5Ui z-Q9zTH{!Mi1_r?AjRMZ<8XAa;=-)16iv}uL<;63W`JjDkqq=ymSMr|}=BBt+{av5SIMM1iwxR*Q%*2w{qA%@Fp@ z?4vwQCnrY$ngsKvxv}eu7cYjjHUQZ^4#iE%_gPm}S8pT4aV-`dfkp{BM!_nsASN=x2H{J}EIK(8S4y@CwM$~t@r+4@C@^T;?#*23Caf-5RN ziIh$2yCV(3F{-^8;?K-hI2b6j;uSctjdgW(K=pG1?KIwK?ZNCUAUR$8+tt<8?4}+b zd>)UGk;yxz8{TnvJziM+Lm>^gnEUzqU|zm;ht*pxEz56Vdia%5Z<~DtJz?~sQwbRv z-uv^SHxYxWVCd{P^{{By$h^0XK0`GUE1+fQBMay&)o)htRDtCNRzSLx?1IwMi5;EL z0TEA+MJ^Mgk8}-8Bq1gy7jm?6+%;VXblwn!h*tf3K09r(i#c`#n6!bt5Hx3DT6SLs*@9gQh zx;pB&K!?yGOF#O$94Whpz`&3!X(?NP$EF93+SuFcXFMCslLmrDK~hZ5yt-1za3Q;C zF5<}HvJR!J!(JCqiw1>|N8!s}c|dZ#?Z3TJ^zpg*_XP0j0%{}_#@*;)a+4%XS%nX9 zz^XUWbv@nHb*u`?)MI6U9^c-~-9|)3wH^0-;Mmv@LOvOB8y_AUOGzA`ot@PTg7Wk7 z4%REny&oQ#_^bNz%CxMk7+>2mi^Ee%OkSyIc<>l# zPW|~)4Y>SWy}dM184-_*bpeA^SsDAw``d^{DI5#h!?zcSk_zjn$0APaH4WBXOkG*e z`8@q1bZbdx_*^!Fq&@LMv-jtR@;(xlN&r@xUdCeud%PSJErQ7zWGf|VDvY9S#h>Wt z$H0f&`GczVr)}vZ-*w)BVJb?-0PPqN&*h-TJJw9+jO_6v*tRc62Y1P0&F59U@$Eo! ztxHx##YlToZkf>uA zs_N>#R%lq#{APcLbH{x*TY}N=YypWkZ(i^nuMZ-{l$V$5>FK3$+YoYD;x=aP0G(}H z5ET{B$MEp*oSd9#6dJni-a+_TVy(?oyB=0}|1qE|&=eknz#5?ccq!u0LO&H1@p_(Y z1C8{+c`#QJOwc7yCMo?a9=psC^gpj3^X5dhd^LHwTNqDbxZuw5c%D=(3dzR`1*eH}Lt!>)qJAEp2Rid%Tc1 zyLC4osi>#`!xhlU{>hT!;>ThsTGGpoj*cx$8^eXaT3XD>5NEj?1CWHFR|>(x;%H@UnwZ-j_g#trE~>owF-g>ot9DaMbMu%{qF5 zjn*d*kB%lZ;;&j4$pA zF#kAdEZH`gh_Z@iW@cA-O4JSgrE&zkhIR$*$Vo{_!NI{36BE>kW&XK2ekH6sA#8qJ zv?_gMoU|eiqV4ZgWr2n87^_KruuqS2;!!6Wi9cys&er^58HE-4n&@1%Z0r*MUQ?xk zD%4cnR!nvgE6b2ED%@lS<;F7-U)G@JK)EVQ&p81#Aol|AgjLqyp7F5 zG<`V2`)xKmUo2CwDn(@YYa!k9J)cwlmk3(`MkVgZivEdo>s(D*Zua{o%K`|8EJO=& zhl)YYhc9ZANRqD?0zmYJrxI^dNqX6ydHdDR&(v|bz)6g^@XB`Eo25Z(?oL~KU_E`z zZaP+~TW+|lt<6ABkJZkpI6km5n|C>zP?V11JA97R>9CMYQ$$2}KuI`m3gH1hosiJY&iPOv3MSB*#da%O0*a^S=CY!jAO0?@MQr`**9#G~w`Z>{ zbOeLPxsx?1)+_d55oNL9h4W;U#ix~x%Pe-o03eab`Y6Y9{PwmpbnVT|%sfL&IB*`| zU}B0GZ}|3Yd}?ZH`V>}yq*`Il`>X@lv}KZfK3A{!zl4CPNa8OhF5V^BcX6^4p&2x| z|1h8NPoxK=3C8&g%D&arIl6sqQDu!0{|J5fp4e&rhyV0zB;J-^ zznmN$&qiy%1EEIytdJ4ojQwcNj~FLf>M(-LT2>ZqmYqMPH{+nR&TTI`YZ+iEkSsv| zFgiMFge?n!yD4M)<|L+<+4;7ADJlX21iEL0*8AkV#sv;t01pUs0>z@bd@{l)aK}I+ ziPLfd+PraI2}MU_bhLt;Tz7A;I^JVVr4?pCN&2;UO%>5sh>r?|uNfjg=>AGm16FwM zm2p!K53^R)r;i^WHmR28F#vV$Q`p3pr;5Bx+2J zi!;kQt9TX;%(~XEnCj<1O=M(Z>cS7l#lyp!#8F?mx1s@^;RE)@6dLDZVNi;cLY|kD zKe!aL_6D~-y{~$WroE|c-pI&1(zsGa_}B;6ygy=b&k+p_1&o%g4Gn){m{$RVvSNa| zU1C(W{i%u>bcBSSX#i*LO$@1EXCu=qiD-+OvUX=j7nRwV^V!Sh07wd5soERr(^?uc zl*U5R4qzl;)!IMx{H=n4FFgT2IXUrae$(j#UA6_JS_0Apc+`qlrDB%Q_I^034<*~v z{9*|0e>mNeJXc@#fzi$5xQ5TqUyp$FD0ZPv8FdJ@a%KTi5u`XEzai~d>3M2v+Z*3d zW~bOLksJ+Wr=k*{@wpQR%3QYIShLWW`hIs*R}gvQdwytA^ap;1Ayf19UifFBrzal{ zV@&eo2!`~&;C9Z-%}b0)iunL}(e8EHc>7eBqNFMu`(LQTmhYcVrdBjYo^X6qVXsRAiVE6evd{7a4euVWM37&Jy-P7 z{FK+F>e8NA^$JL;3a&e|jr?PsgbA57Z&Xz)%?Bx8zE&{H_>(C0Q=q zYdqD{(IKw)RGVQ{Ku$ljafy1LK7hTBKvV~c+0oVIP17pfmdedY=LSf)oczAMpy3Vo zc0A+ctnj{xt@_#9`}!RwiP5t^^o<|70fn-*u^Dt~d;griFN_~VOeTIM(fcIX1>`;% zEn0ZuO6}Z@vQm!fCXx2=9n$vd!a|OtpABMTJjyKtH_}KZi2ndK^!ZIm?k$7I;uwnZ zuKI)W_!EGmU3RCzHTQ1sB>i)}fP2s>W?uF3%*7TGMixCCZ(sCm;eJ1D9w~AHD`2$! z0c0h8M||u#8YA?!hZW73LT3-sz5puI68Yi72cX&)p1w%IHFL|2>3;Sg{73y>la-Cl z>pg;S&7TE-cl73tfcm`REiQGBOa0JiDk>_3M!j7cO9i&XY=J&KzSWJ*>zdr4#y zXVH_JOQ~X&XE|V>)wa25=~0Vj97d0|{@rvu7lV*9EHm9dGgVPM&{#d>Fedu$LHawc zvuc(ZbbiX2jL}Wh(BSmgHa9k#_CTJbqT7Bw10NSMUCzAM^0yHa2R0+%q=@?R=7_3bu{Zhy#yI%>6;&>P0 zedac>M#oc26Z!b&tIus|CpH^qQ<#FmtR|G;cw_KS?=FuwoVLdyJ|U@PIP3oR=NK}; z!o=hRgmQbwC;Eit9Kw(lXDN_+uz3DfHuy3RhR0X`3RcP+8GeU1JaM>I=Wb4TFfn6- zf{=Ye5T6>-4WQk_%HEtypj!gN9VF9`eL(@=^9N|&!yU$$DL^n3#?x{k&6m6N1RSP8 zAt8qxT7%%SckY=FR*uzU@a3wUt3V``jw1Yf@z=^niivXjN$~wSqUx&NeLfum8ucBr zBq3fC83$6AZ;}WpP+srvKnuLU56}~qJHxdZz|s^p{Z+GuC{%uNiaYE_E;fc6i*rJ2 z+|zt}y$1pfGNk7Oa$#j0xc8sV6}T9Td#m*!76KMK87^*XZLt{su+lxk3LD^h2yT55 zJ_id+@1H+OjkqdE|L;=^f_&BaF7{|{#q5*e-_1W)X5<6t_qW9mdUxu#XYE%Ysby?s zrLCgU(yxRW$D-QWQoRY4Nzq4)zEI1@xJt5<;K`J>hXJ643zqaU}>i zer>)}ykCSIl$5#U z<#BfEZRxyDmR43>oSsO}TY!1HA?WoO9epDT4M6$3oLVE&58&W+eu<5Z1@<~{TqfTE z>k|MdMmuo>OYq&c0CoWpV4qf4oP7No{wN#>Ntlm4oN7lv==3BL5v)%&GvFem3i}Gt zmdW&I3f?K$^#~_@tJ5S%ywfu?U9AA6{_gGu>BOiTz_`IMaIepk9lnVSFL}{a17xj3 z4&(rgC@5@oZA}#|ASfsZ1Skdy0guTBq78;=X0RA6< z<3&e50{$h@NJz*dN21O~&(ooHFtPz5Z`jDs2535Uq^*rcJ!cGL7!s0!OEg>`1+02; zFX|2fmrY#V_ho>o0aM1~w-k3rs|p}?nk?_+HFH9yGSYB&df@K$!v(LGv>zgJh-Cb) zsSH^e1qGkub?gtbH8yF78FtFF!oVs4nU{0~<)q8YODB|fVq#(!V2N)G(P+hMym=Ep z)r$e$J>_Wv(nQ zkM21jMF8#?ZXf4QWcSBW72d!d#U>$%N&+EGuY)$cJF}Y0>IKBq!2$9jNAN(4{)A!+ zD6g@}cR@;{TQHp1ftf_HW8Gav1fvWk6ZANCoAd7I$3pEva%mso>OjV0)fop;88S-! z!I74OgM%_REu&RUKM1eI%0JuT=HUUB0Z}z?Np~m)i3ezwLr0(~0gH#7wn9G4u{)7L z(-4H3FGT7$Ha27wCb-g=cYfWiHZj4{YkML@(GKwph|5fj?Eb+40q{8Iy8Vb_w=06? zYiws288EUdJIsJyA1X)OMb&L1>rhA2g;NA^a&iLHNp@{}dm98rDtQa?@iQJM4*G&M zwCRcgCj>_Tt7Wpn1bvPX3y!lH$zb93CH?S^hCU!>xP036t}Kp%ChBnksn4*m*u5{D zFPvL~(13^@zqp$ezxc!zzcMGs5MTpi2g@GN88L`o#d1nXNdX0&8aVKTM}UfJa^%bE z4gTIjIiZH5?)-oQxe6fn+p9IFoJbgH4Vr=}w z$Q&5i)O6QaHFk3fj?kp+X;NKj?9;To z6G%QMrleFB4x}*`*xoHQkZrq*0bD)t|Irf*>j8rfuwsg~dXK-1!iw>+iD#FWdG>F3 zu_&og>kmpwMn*^Pl$*k`9Wc^!gbRM3ati?J{~@HJ5Fi)e?E73_{LIv?b3UIB#Jss| zz9q8r%RDmfhSx#dz@r7|vPqqsU3eK^)qoy4371)FLm=}9CbY$4coifsH`fRT@>Bjl zn6cYAA413A-~{(3D(Pk^L0e-7In>t(!(6Lp2TRr8Z@-Bc(B5@kTFV}wB7uZfILCWr z#P^0#7N4+#Y1#~Ay7yQ>t`^wL&;*AC&N7Q(TEGB6ghKB9uL~eRt$J2HBO$q7n#CBE zhypepDkMKmgkdZk{>i!=v@wt)7%T*#>L2p47VtXY>Ti1WMxU000Ri%L z^B=)9dEKr#32b1{pJ%nQZ6K1cOd)SVv;ur1U2=ms3us^r2yf_-ARo09gV2&zwdM1S zVB=UWT6sgmoDkK;+p`YgXRyUyO-)U#a-(Yo1_qGzmD^ugm|6jC=}0ONQvF?S2%qY4 z!t>m?WjOupMgW*0V8v^u>*ybYTLF^yFRef#N=Cy%aei-4kxe|eU7{!&*$IeT>sT*d zNUc7G9jd)~GdVRCfvieCuVe<*m0n~Y32ULRlJ%64L3I=fa|iifXLf4b5$k9)*pL=c z7xRbgyb4enS$eh-k>N=|QCI}|2651>EhO0@yOwr#G7=Jg)jmcxjp2iB@=d1YNa2R? zEpWki0dEAKql*Ig24tP$;~{ZTLnbyhHsO|r;zNkAA<(XjgWbb{rp zcCQHFHW+aH1rT>1G{#El42W+lb}(AmIGBr_oX7xzL_t*pA?mAeV=+svRgljG+Y3;1 zDgU%>>D4)Rb#xR000O+f7P#Gy&;Ye`JFstLGpficnt{MvVganbc+Y4Q6qGzhY1&uL z>q>C!XeMT6AakE8$Q3(6tI7m{DHJ1?ka+8!4$LMgsgV3v*=&wIJRp(@DrWYpe)B5m zqKJRnM_hzyMQ_4dRJNXWt7^wwm8~bjCdbEP(Kc*qL6pP|5G*Bjk{n(9qo<(8l8PpV?Gb9da2qwozfDGtne-`Atek>_?d7h}z?TcbN& z33Omhie!s`0_gCgdOY{d0qLE&j?OeNhymfNv6)KF$e011HHd#HDY09Q(4U;d0!q6( z+juGT5SUTMxnM0DFD57oM zu(yY`u&)B=3qVTEM!ENa!eDp+%ws%7CgASpmAvuy#kQ>cdeNclS`gwxFDoJ=#`fd= z{a4->oS;XdYQ@2z{yFSuFktJy1NF4nSBL2T=x)g-u&;t%4`T0KpkNTeb|BUH4xZJl zo8v-O-MR*^^Y|6yf|7%j`39J5ZjQa&rT2F_1&V0Teqs zh$0{)OpT9ksU-{mNJ-f1EcQ0$p%fKA|0SThS7YStSOA&+h_QoeYfk~#(DVn3UO$wa zo%>AvNI&q02*5@mgn^AsO+M|B1jid7(masGKZgoZH|hLs@g|+I6ztfwVHSr}L`T4> z+XTFF&XW8Iks+c@ERG^#FFtqXQ?5ssAh!iL88ZXplSyANzTkd|pn1vgsCh0QyN7=t z3DvtAj*i7yc*MR6cp|MrdS@*m>Mtp{2+?wDf(XaUrHOf18C9Hs{rnH$!Ge@RA@oB4 z^C6g1O4O4;&JeVl6&Q*N=mV0_Pb<;-Wl6AJqB=}|Czt3qXKq0rJg{EH=uk)1@uh0HUc!qp~ zLqjj=oJ&6@tqcV{FUzkJ?vc!z-^b$1_IpQ3mx-LJjMrZm9b@qcGL8m%4@eTxkDK+t z{f&qpRn^wcRaa_DHIu%f#Jj5a6tPBT^~BW?=I|;-ZRJjz zYC=26VW(R%rR<+BTmD`-C+~Cajhbk|rtgc?sei~YbI-HqZ zW+1~}Sfex%!+1M@bG;@VbjbAbpPJcRd^<+0`f>n&8;dpa-PS0JQIDVB1GNfbRcyhnhRHpGsLc#{%Jluhbs=GlA6 z`sdn^0mV$(MY_NFV)L`jRL!8%u!y<&I%s+ySnd1{L9h5wjDJ>FP_PQH2}r@Ws;a3^ z%ZzjqcCPY)J!d3X5$=&uQGX8)fw(;UNjYyloa!!DWMBC^V0G2h7|We*bG9bAGn~%f zl(V&xyQ7;Sgd{M75Xaj9nz*wbC?fWXfk;(__>CA0q{aJvPAUOY5l1{`SF0CM2>Q)M zE2NZ%@iw2L#V7Xg(2?lUr<+?qGh>aTJ1cG0805RWdIKr671m?-p_wJNwr+}N}A#o2bUws4cy;7P&R9*e~_bjrB z;N|7zAZgES;Az*#M4Epboj|zrgy#KdwXjQx;9bM zAN$Vmva(P6e(NG8x~}C{S9Hbm9!3+N)_wJNvg5%PikhZUn z2eSOD+D7Bl`_%y`!TY@!P(F^7JrjT4{ogjj;ry=q_I;m8U9AKm4glIe(ZKY}AT}6Ow2BJvvHw*Px;xfW}Ehm-#S6 z?7j+oO3NP1S-x79fJ-VyG}5W^V%`)Sp~Nn=u*jRs+wSBjvIuQW))S54{61Nq2-Gh^ zv`$#~0`#^#>YS+V_MpjF>})NH`q(?eLW{KS_~b-EU8jy8qp1%pC zq-znn+W)ov`ynuKZpef~A((Gg9Cx~XHD6fGYZT9ewX-$$H6|*`gs2EIQEsTTlubBU zX%+*rVw7L0HO%cVA#r!;r6*I6h)*iGEt3;v{P%oWJODD{-+-^z!tZ~#8Ln&h9Ow>U zlL=46MsT|OGjk~g0dyb~p{AJh0GR=pHb*6oBo%@v#MSyBz8Aw;E$|7h2HB+BGHXTo z>Uz{Te6an`fD#Ore1E_UWYu+atqcuCOC!jwXB&9w=%g({ghxSb4uC}vY(T5cWo!mQ zvWW>z{A=zGXNPx{zT_MnPIm>~4Mt-|R+g~!I6Eh$i;abaXgedv&&1`n`z7-49m=I8 z0WRR2r4o2>pX)y#`t+R6-ae1~F5vL7g7UjCvwSF#k|}7L-@ku<#_=lPPT8Mz`$yTA zVV4!^B*fwR3-XU$<%eLbip2pZ$9;RWWD2whh@qJokHL=zj=gN%ULIeF*#v=(0cF;2 zBDR`s^mN<$y&3aA-ybOTs{w@jGZ_c|GZJjok(8JN25{c4=PgkkpV3?q5`81jicO`% z#;L_=|F=xh2(fXeQF@RWlMuYw(!Wh5-p~2Ou?kvTCo*I;kwG;zH8sCBD*S(JpZlPr zbGKQgU-;H*^vl~@y|{qQ%}tQN`~gXbqdJZ}k8#uB`!^KtLlpx=sWWpd#`^Z0x>gUeu9P zERG@A%!@?4^9s{cr$_mnYg{#l?`lC~LSx+#gyIXRI;W^Fkd2~MkYEH-DXzdXPh0hWq>b>kN?BXT5Tuq|MFCi*sMx00;(yRA7B&r7ctAE1Bb> zY&HS!0d)ME0~JBdOJ-(fCMJ0mog#k&R8-XY`kDat-QhyaLf$$DN#bWS2HFbmDG&qR zTPN|BDNAbt+|b1Gd9UByY>D9W#dc*swPXlFe=aThm8#I!@?e7Pb}MC>`lM@Nc%bv-?e{HUM%iwjpc#GMU06Vf_*hstY!|WJfee5? z@W*M^s!KG>5ra9nOTr@WlztU{FmHi<_mYD{`E_MpvrJEtfcp%1L&cMF1YG%>5-mwZ zEh$AZGP2fVy@z22L(%zpfB}G*V6u}F_5E;9cc;Bmt&Si$k35PnyE7=nLu5*%Ne;pu znHd1y9_dJcKjl;=NFWuVLW{=hxs1}vgJ%@6t8C)eSi(G``A&~W%F_?1IVp`$B3IF z?Ctd>B`nu5sO+?iyiHlpK>JUI91tw<^w$#Ne!vc~Z0l~913MeRUir7Dm4iwf+0o?H z+~<1d6D8RgxpWtlLa|~-zhyIX!$>*Jv3Q>03E<=5xt;ABN)Wjnu+>2A=}AVhwB4!aC{IA#S)9|sTtYK;p->m}^*_!jt=%QCHsW7)8EYYJb|m^M#v^uCTlu+b%raJ|HP}D-J-jaLN6e zu7{3Dq=d>V@xz9Z(F(Hq-<(jLrZ@r26XNvc1~MwcDm?L(sYNrM!JrLOAQYYBm|M>kXRydn z{4qx80yS8mF^#C3O9tq8U>FJ`h-qq$W9l8z(zTcnRDw_{uu1jL-UQ~dwm2i|KdLF^ zzP29SJ`b#**_b1X=g!9TNUdb0dG{|2_JZ2k*(FXb3+T(1_YbzU1q-SoYWdHA{$*xm zC9kCktKdhOAjZMb%$HALm3fvFb+@lQGQ9XhFC;ui6SlZB$d4@=-3kZV?T8hVM(HvL zlH+EbUK%u@NN(D_t}m*~+0M>W zE>MS&ym~?2Il50F?)QuB?m4IIMRMj3t{3yW0r{WC&FReOdj6E{4SD^0(=*x)q%maV z4y&rFfb(x)1T>=U0sK$KcQRJr2uMUxL}?MKs%&2*`p|cPoTO{2Ds1tOa{Ta;7-z?H zIjqCyA=sGs9U!aG7&)B`h@o#{*#PAY2#xNgNA0+)#fVr%G=e@KA(e2;JdzbPaJhDbpAX-JrEgFB>&%`p}G zA>l{5MNMt(1T>fSAh@}DAL;uMgB}1=YZ%u~U|^e^L54GfC6wK2lv(pxdm^p^pwxbH zcNzq*x`SP$T3hC887!Pm+0Z8hVs6bXzZso+fI>M~T_k>Yf;}MmY^`_pMm&$T1-V`P z4*un_W>(L|prsAeOOQVdG-{6~NsEg+aQ(`2407#I2}#MH@O2P>{(lJj?r^UA_w9(R zWM^lKNSPUBla)O~GD4EAC=uCvlVqiCk`ZN7$&3oAC@U*UWi%-9oFDi1d4A9DIey3S z+{bbMQ+;@UUhmiIdR^Cfo#%N4nLdA@wzc_J+bu@(=OXVJ$3Z?NcxMn)3En_`M}zy| zO<`7MK5)BVE8fc5nw^D3NLcd{8R{?q?p zDhl!KZ~JjXaMK{DAgHX+h}oWanul<05754R2Qlo80$rcT=h!AZg2nFLQsP9*<)>PH zLlS0F`oQ@)n*`myefkxj6Oxi#UYfq_>EVg%f55n{8PpjoHTh@IBh_L5Amf>ZCG!_|49cA8cvKGU4VbrJns*>pvBM%?@aWO)CMFubj$9PxYhqA$bqkqZ2y1$J6y^*{mcK;=N6`> ze7=nzYkl1xO@8j*^qx2G1kv_yyZqzR4=9uV@4uVUnoCOTbG-4JeRVoXY4hiM&vkP( zzW9-!+v}@-^ae4mN(0Bu^_L-E-;}dYxRJcO91aja#rm5u8h)lI4{Nj82;b`Z&wVe^ z?4zsrNBl-k4q6{;=6u{rZD=C2B7K=74n0!e)HH$o&QAFWUd}_-K2}dpKy`Asa7$nX~V)*@tEv%4RQ^~9n2p6RMl zR@{C*!l@swvJWbwOXji%^aGI<&#UA~RLTpY{ue{i8Q(q#{yuP=?W-0MxD@|Qg`Q}r z+?ihc-!$mDL9S?N!n&u(;?DuF$ZvlQlT-~1TnApv-=XX3%Ozx+LI7sElUzcB5H<5U zK|#M)S$PP{GjrS$W;8zurb5RWlw_lmlKzRgk)NNxLh1&~4j#vKI*_sV^bCrVgMkTM z6(@N!FXuojK(q6qt z<+zuT@d2B{>-X<(>@h1pvc0L+mqnA4usdI6S3L&Xblset_vP7GEg-)P+#e z6O>-T1cv;!9G&xGp~kHE3E=Ju-c#!G@gf`ZGc)PGf9^O?QVC+q%;cmOcG56)a65@q zY}RAP;9x~#{fvt#@UjqT(LO{~ZCc!delxe6APJ>o>it@Hd%R2(79k@fJ-er@0$+)^ z>MoUyv|K*2)!~|u*QsYAYf2F_2yNbN%YO8@&n?MWf%w_?+vZSke+9ug-R)(E@7 z7unD1tlKVg|9U5&oc_J_!y0YDG?b@4`QCer>9;{e)^BVNCFLe1aSjpW?d&E%U4$&A zwWa?TH{E}Tb*&90#afa|n`@5gUyxcKyRgU-Z)IYVcDKHz2m2px8Lz2--iD4=lXOCq zlCfP6@_(e$56$}{7e^abfj)0o6j5DbV;DbsEi`WP_IUQY31-rVk}Y+AQHbMuf3|ZS z)(GI3dMAW~=3sDB-XARCjorH(`XD;_-X50-?MIu&9V7_1-3hg{wYBx5fMwz{!C1a@ znpwwE0Q{nfY+MTm<70m9NQmXA;SBw@$4*RU2F-zOFcAc5T6Eo z7U!O>$LC@?ej_G_xKyBtEA0W5V=Xgife~Ww58+!r8ct26Z+%T(0u{{vU(_Bqo=x#z zlJ>abdRxZl;zqJ%Qi7lSeku}aNuqSBfi=y$uu&4LkFcb$bW8_AdVQtylUAd~u_ z=<{?(w(dywv%oS4n2PJ|g`bPt>p9)bCD6fUrl+6YB#LeP)ADN^G&M)biNQhRH`x*| zEi5!yUTID4-)VcQ-YXQpRcZcgAAmc%2A>E|X<`ER3MtYeowko;GhQdc<`vK`N=g?* z=V|2FuH24cBD%7P|AI3ts+z?~aV%jSdBU@!<=SY+zK5~ePGch@B3pAaGf*17FkFdWM-$Hv z_^qe(p0@1sP_P%$HZBItJNChN2t=K@|MTZ6`154^Iq*KT=2~CNX5SHiKP~&@9Yl{@ z)!&TgtEUT-#32s`2KcOwjZBRdWOb7pae>Y+a;9=gru3hQ zQs;71rNzDc(K_K;VLZjHfranize6{eO`e2U&3(;6Css08@z0_pZz&z0Ca{Y7`ua)g z$%Rw_-Cfjd;dx&!ZY%cFcMjZ^l^8b~=*oti_y(A;6K)(%Y&BI?UI@ot9AUC%;`GNg zG)UuFkq8 zw3}|gdIfpZQ7so9@3miS@4sxXS}B)$*3{j+#014o7)_xsDvT!{Vm0Yak)>zSiWdhi zY!JWx>9xoPb20mOb+NlKv9Y{oPlI)W-0^H?)DX>?heLT?6mRfWk8$s;r?9;c@LilB z1%B@=`yr(C$Q{s@Rk8>YSIV!9v!Fm}w7_m6cB>s|r=Fz}?eS42kU0;to6nNvjV zr`ls?9KQTi*p{S!q8zx*lG4r5-<91jP~3wT3U-K(x;?d=v#+nDsHSIQ*bvQiLAUch z!t(E8oG4t6f9kqd|My=b1NqQ|b2Q@Pw?_(+#EtquKwK*CRM`%BuUQ!k2&kb#{|iut zzP0`l`~A4MiapEG*s=E2ze@MZhLL>qRX3+y$mNBw*1$vnMPeI*)Dfa2n8z!kzM^$W zHRZ{ZC%DVH#j`}Mh!5WF6Mz5h-&GZW1nNOmmFtaA2U5W>#m?O@sd#zg-_L^-a@6Ro zlHlF_EWW4)2%S67$fTX|-YE&jQmJ=2PMKsm(!U$~_h%8Da{2{Sqw{&@`{y0?a4kK1 zrh~2Tdiaiv`$X%_9~Q2zLOy-CS#EJgETJ(WDRJkJaWjsHws_+#Tx0|~`qOL@dpIwj zy|}%J=4gyMwII*jv97A-rw zuE*;?DESdB-?c(g@s+LX!jbJ4Y-{Gz+^@2UkI{Ax zDMNr8n}p^pcwlp(ik<4uquY^S|L2s;SJ*TV+oCR5l_YV#rr1e9Owr=qk1q#>9`4Ws zrInR+4<5MJIOY+*!WktbdlSKb4q}h~8%WL&vMyV6uJQAoBVQ28T>l$m)l+tD*-E?G zvN;GkT2ztXAt|Yy4xV@44k+^j*F2@!?wr*V-_^A4g-Z-LEHfh`SOm^7_z@dx_W>$R zxJm6k*H=;^lyS`hLY3&eje79X4Gdlq9Dd}uB&1(IeR^&8BTZVzsv8t2g}>km@$eAC zuc?@K*K_x=M|5)SmJ&22w>J8LFzEuy*S#2!In*x|t?20Kh2NbILofE6t7|eN-y?LC z6CcEh4?mCU?9_yJ7T9`N(fEOpY~(@kLz}cth}3gbwJ$BdWyWjA9mA60qytnW?FH-|ynZq@<(}SOjI+1#4e!z4U|fIv?i-^==T6^pYWj#Setwb;Sw>CWY3S20UDFodbvcUc{ed7lRAEyfPF!L^*gPyG6peTF zDZX@eExTKYY&T2)&=4altDG$n>+>wruHm6QAsPa`V{b%tc-t?(8>|66*6b5pu%81OEVk zlP1I@PP6E%6Fk;6SgH5%s1FTtq+&qTd}|j1pR^@3&p%&0vq#Y@of}P-k1i~Uv9Ym> zi|(5Y%nz7^CgF{CRrbRpmU66Wi5eIvFY4H+5%K;n50Yuq>YM0i`bL1gGK*@h*}N0Gb-|x;c?a$BXWhI}3>; z-?>qyL4k!!jNt1G#$J0d+5m%qF9(Ds)T935Gg{5LiR{gJO0V|T)`bH5SQKt%=hzD zcm)H0!zsA$zm8gT`T5kJM!$tYG!BrRB^;u%6MApOTF*3bnthbV%=ReNJ9-qHHR8(| z-=I;&`v*FB!*Mp%!Gh0NSE2=i6gRz)kS#3XD-S#duiPA==J>$<48abOxUDuCtG^>i z5x~h~%|=TVh$(xB;HC8I%lqTMl~cM!mKi7L79w{u-hjP^R#2)X3Hv`Go2&Vr<-g8v zLbO>}rJVEf_n=m% zbF5-#ADRYG_!rGLt(VSf4QTwVg$VD-L)Se;GswI6cjw2AUyrtKN`dOy*wl1Rvh9u1 z<}%Gat{d9T97-?AT@zgx7s=ycb!RhXd)e~m;!vrHL2sVNSC3*D`q}0}bV}se8JKuS zpJ1Cjr@KR~wa+ZCpMj0-?ktfj|22YCWXdf5iHG}Axk{iGkCmhTb%|NKSVxs^-jNp^ zw4cF@T{9QJR!=bAS=u5T-x0z4^vTHm{FX0$^N*=VtbgWd^)wlWAJ=<%Qr6|_^bTf= zENC&e#iE2Yk-PZS##BD2Y@nako|q3{Q+(*HTYSQG_S!!E9Dyw>175{Hi`h}9z3AX8nz+P9RZX_Q_*FMf z`;E7cHZ$_=gX#msgbyy9c`fo~l*T1%k?Xhhh$X9I{v2-6H9=b-fdj~)=3k-nj>!Ay zdbz@|yhF`#8Xmp8qYd}(FN1>vrl04Dsz5B=dzU27p=Vr45t7r;#c6Hry?;0i8-Chs@q}iT?`V}l-m5=Zi1^#5Y zo;d_{?BaFynHlP!HTQg^N8DdDq^~w0G4ybAOJ)3+FDox!Jw^@=&L|}Xn0@UQeVZm| z;c;K8*BOK+t+TV>xGp_wbn7cQ2_wLe@l%k0=3EDrA7O&pLTMbM%g)4QZ%nJS9KhogD7tw)V}~A+S_}%DK7oy%@cmLZm;hm((oQ>|H&>MpU#m`wVPh; zCo!djC37!s=#&A;vWFRe|bcg zx9%K>Jk?&whqS<*>FdNJ0|J5M7HudmAfz6GMwf7HG~sH=RJiKI#z4V0GIp(;~O^j*koID`b~a1md*W00R%nSYPy*x5Q6W&NYqMb|bU zBCZOYc6o5n{is5tyhr!Dw!r=)uJki&FPgrI4l|}%W!x}Km2G#))^T*Ok`EUlx)JDJ zm12B9!6}}lb`~*8>aue8iR%&_Z{IQt=QX}c1EaNJ?+jVDUPJz_DcpzC-TbHZj%ox( zZSa|i2Nn6;HhA)q_U@Ti%uWTyp9}6ota0lsNx0UZ9kt_KFFBOVavXsz8aGUDK?u$F zxp@0xTK^EmRXeiKx|Mpq4|feUyUcC|p?m=itpqNmyhW$$kZ$-Kt5721RR~(ED(=j# ze87I$@=qm4po-gPmc@U|7eplWzgixxksO5w4;{z?GvaJ&e*VNi23-7nc;QhAAHN=J z{C4d6v%sYzH%!$KF@NmcXyEI1Xlo`qh*G)_ZNk1oTLs7J!;P$9#qT8er%GnnhNpn$PNjc z-;5*iFkE0I<={^9_wpjBLKp)nYHSV!%25VS5;O~f>X)Wmbhk~P;n>M_UTF@Q00EI} zeVt7xir!{qWoGj3IjtN`Z(tPvYHWD;C$AI$K8jF!7khI8QMaVP=-p|wfPNA$5r662 zC+NDGG5xvO|MOn>VSqWNXBMxw+tDZM0sD=um*Y2-HByQ%PfX-CxQr|O8khWb<>i-! z_ZQBUm49g~5~8Fm;r6Kib~U=FzLNWZN3_tM0LCYzBKVBKc*D9LECk$rajJQJLa|Dfmc z`!p0o9?SnLjbzs@dR742l1YbOAxUdEIwHW${kTIyi%da5q1pUWzW#@Z8BSQBQSeDz zl&IvSGXxRaVz}(=&Cw4}(?fPx>>VV|ReHg3Ff=NP%sRF^-DBGLA#Rw})zAHfPmybR zpMfSbQEFek78)#y&3c*%QSAR@2T10!dOqZjWHk9OssXD3?zpAN%XUB(Y)CBjP!BBY zsu>h!_lrKrq!p|V6Jtz^=4OLf&r5^)Sk!QI=JMklzf9zP(nbwEee+Ss3=|wh5(r@cq8U8$AgbH8x4l6@LDz zC6Q=y>Zat3k8^XW=e6}?J;xd~F8ZtJ!CIJP;mU8(o@Ek;J`qU<#aTy(aPSeVO}>jrz45&-p#H|HI!WWOub#9bjI?gP8Zo2)ol+->LtR_FNraL1Uar-J`Tbg!R zJQt@ho!#^?t<{Bo{g&A4+1a4ea@BQk(~-;d9CoS}>8UKruzFKrTV^3n5f~V_*g@>w z#m+OS?B09KDg+P=eV1}IUBu~&NN^!~g3@Y;^J8)6(*zT}5@k3&1(XSh7ia5yb)5R# znMHoK3H|uiTTmaUW%th%X{h=>0GnDY?1s4Gu0f8Vx0f9C-Wjq>|EfyO=kT8Ym>-hp zoU5J{z$gEH`N%}jPMZD}I!7Y}E9t8;)!J!-;B zdAqeC!rHFrI!MbhB7Z4=Jyc)iUH_Dh4_Pk?Se~%%@L~CM3I1l{E;u=m32mOfkprs-8f)Zqr=m)cx2^yEPoQBPTO+S1|APyPkRgBgQW4gE2fE z>FGZ*rn5Tb)P$CwCR-Qig^|to=P9DZ808&VL<#|~ib|IMq5KHsU0+|{uhstCwN)2MMT^8*)`Q~j z&!%0!PEmJ!@afQ{tmjT>qwn7jxGm3`O*vJPzdZ@;wZT6}Wh(@mX@leXVjfPHFIei& zcy(vGHVgOYc1%j$wWxeS&6qJGeR|0;rB~-rKo5#-y3dnt0y{T_aP!s|%xi@1;)XqN z*1quU7Eh6$!FZd51gX~n_1>{DG9<$L5tYvf-BCq*l6w7VWwdEl%SZC(4xT6P)t6Ly%)KeK7@Ap|b$ZQ-X+N%pEHD4l%?ttU$Kt_1dfX8p(nO=^|4gx;hMk!(LM z#3NGj@;P-UQ>*a|6xhI>&B1>!LBIjcR>v+o=M3_Y+Fe82D|Rt9E^fL!Q#~O2XUX#Z zgDQq{7Zxo^ve_yU-r7PD{3uNHcsbYE4ov&5w6B+cg_x+A;|XUZ)123a#8J-Yif)CzWq13@&mK3XP!ZQuLl1{uLOdi<4+g>JplW-|yZ^`lPQ~~)X z`5i)Fii?7kFR>BN&FC|jsNr-AfGRp658mOjvg}arwyJRW3dY$@jx^Mh4vyfBjvn^c zK1H1{FC92aUcQG!>gdrRbV=Q%)#LJmR(e1X*dixp1=^)2=ptZ)+(TaeWa>YeJV~Lc zv)71s?u4U}7N^7+p6j=PkA4U^BqZoyd8rQu=w1dMhS(J{+%x-Y0+vb5X*L4UOI{^q zB2yLG-a%m7?Q(cxeNdY<*6OQCDtLUwsyh=3(tgyzSJJfQ7r>p2vTP^%v-7vW9H8I8 zJx!8?f>Mxyn!7+mNNCNgeX#14+XIiW9Bcj^)zJ*652o8cja*2ur*j82N$dBWC?3hj zn4!YR6Q^$E+$VF5|+ zs}S;Zbau|o%p^BOk=S^-fLXgMqUZ*l11qr*218$Pon!7)S70SiJpJ8BBIc zyXM!ac-V-V78TdzWL{F|1XJ;m{elF|SbVl=HezL;B3C$LuMt%g}(37jzGKrK8tBc>T1;SYw1E@7Nt*nw^&~ zU#HZB zK9OA7j&L?H(6c1&Wotd|u~GLss2yHJn6IPTJeafiJ%rq`upDfFqH`MB)m4L5P6P|w zXRHMC;50uk$^PVvk1!`d^3R9=jg)ERrW=uWQV9aD>iB`c&G>M_(&i`A|LEK_ym&xPvp%StIig2rb#)KkgW zd8#0?cy&{C0Yv!xD?djNroCpskoypUMAfN--ecY5=NOFKw0y=2)yTB-OfvOGlIrO{ zu!KjN=?z-wSNpV&MehA!Hf@l(T~}S}dr_+?wZoS@)THAoHwTb#!!m%4*e7 zys(5&vrypIey)nIov-PPkf3Rd*d9{wz!XhWRZa+1;#{}A2c1y;7ADLbE3yESv9XOt z<06}dW$?!G@e3b_+ViH*@CR}qqjTu5J_F0>tqR+wRI^BOttG3DA%#=6%+i}q7r6g| zpSkvFE$o>#>*hVyMNXcy4}xbaZAzBCrWw(|H=6d)$=FwmP>XIVyoyDk0UvEI{v}Qn zb`PUm=*d()sEn==^S-UXHoSC+;9>1u=<)6WMd-ddO1UuUq2u$he3P?Fd5{1ih7kq^ zxJzsAGy0BRJny@)dT;2MXm6go0)MHkRi!QTxmnc44jF3ZN{+h%591$9pIJ7JKEm@A zw1ucOeKazt@&y881AcG31h@f5Td|%){58)^%d!n^quxKz} zxPJG**S7lu1)prW6439~7-dfod8cnmFkr$FnAb_;kUe&RHd@Rp8^mv^mtIO7)JleE z$Ms&(dH&9D`a`F%;3)F~KeCns$9C^i^Z9}@|MQCh190f1S{_ExWM^d^mwzH4r>EA| zE8PoAHq35<`r-~Hd8k^@agS@&xe6D>Adr`nv${xE25%c@XJ;SHy|TQpgny8+yYho6&@lV3Q#b7;N6zPm z#VFT~=A6p8$L&!-bHbE&I}lpIhB<+2S|hw8#3nQX<-!~>b#_b3u^iUcf>g)79qOwF zzI+5Psj)j*iXUV!>;oGgGbzxW^Tq$PvMfMHqcgLcbR{uNQ$UaL?#gCm8$zWgYc?3-l7MY+V!&2wyA$9q>IytH{W4d<|G* zOJ`b}`Ck@}piAeGAwF|tlzQ*)@EiO}v6>!t!1I37Z(Bf0wRbnm;j7LkyFE|Vd9-}} zJA7*4?<P01-Ws;AQaT{Vy(wjV>lj7U|7mdYj}EIa25fO;X*ZjNGv5S#xOj z?r%kuM#N3_N|L}Zng2pr6n!FPrBKIp3!SQlxvj(T>=>DtqxX1vLS!T)Rlbj^xg7|mSKsN1M(>)5a1>)+0(cN-Q5lg8^)uc# zk4D&56~{H)4^7@S~KBYsC@WNLxbFY5Bkl|xTdh^Sd!d*RDFf}a{IjWUKsnPwjq zA^K}u?L=|?bDSlduzP~U-z056LW(%JG0Wz@z95hOTX9wYp%Kq7s4dAo)-OfN0W}FY z#W{ycd{~V2W`BuObcdx}ePxT={->}+cqYg;w}_lCT#)he0?JQt_V>3$|5*ZFGvK4| zA|>_KK!N78bEVOtgL2{Twe!hF(ZYdLMcL$@H>A$0+POYQ5awfCh3(bTtPbnvl)*bT zRNeQN{^zYY5qI03eBgQ?2duT=fN`Xf$fC%8pl#JwGJi~2$XZX4$m47#&)8*_?3)FM z&~G9k`3AMBA5)ql_i=@h_YcnU^(37Jm~hQ9+Cj%Bgl?qDXM1nP9BM&Jzxnk&5)u+9 z>~1_v|6or{g_VydwYV1-r|aOrYiFoo^z9{BBMH&b!|<5lr@5{kKtuKO0g4|lr}7%x^c9EKPorc6Fj*5>(@&aJTo(H0VFW& zgNyja;pW#t{20dfcJ>Xa={I{~M}#HKWmtV714N8&E%=1EzPhr4Gye3#JLRhSo*e?~ z6c6s*yN5YfLOEY=d6XOtT$#~`+v~l`GAXbqK|~_oBobkJ7?SwQ-3s11dVvDU$ovbl zyNNNBBCzbbkfc547=ckd>=+=Mq zurv1Y_4RjQrL~O4^hsa=b+fgA6pp!iV!2|STI zAdqlgDP7GyB?7w*T_$JJSpQoXkz9}X^z`%y7nrBn6Er1TT3R0FD(V{=9Sz>F?4Gq=6~4pz@$^LPdG;%! z##z`~Z1Rc{`Ykm7d=9Hq#Av~hIrI9q1v*^-KZMbdI7Yer`U>3K$`=ocYUgDnDyW6q zL`L3XQ|0Th!2#6Is>`8lRl)g5c>9>vlpNhQd~F7w^*2GWXFKJF7ud?eVKc;*qn5T) z`{VF^u6@B#K{bv_U`DEIVDz9TXj{XNb-iAH{P^*e8)`*NKT}$vSrIZqf!Vq~cLNzZ z%HSJs?BV6J&YdZN7SSTDkpR{$fZbQ_FPw)Wqjw&pu;VWADKPT$_y0TGY0K6o8hf@- zZkPfo7;^%;QGGemabGd_!fVY5B@kQ#wILya(|FX^XmXGpTa!J z?2h3JpXC1FHd1}N;pE8OP@WD`#fvEdbEjQG9aIeqstmL`fL3+YoKHnE?5FzoB#ZN2 z8ih}e=xQ2w94^i_mmq6uAML`tGS<{94+4XzS;HGkuI8Nij&5&fuhrS7VovGi%0iTU z4n4^EQvD^mt$2DnpA^ct?s7e&ttf!4>{Ei+3-)B5dm2S|#;p_wLhXK#$y0h)kO~Y= z$(z@SRhWn$c>;h*sb3}~ei~bf`|R)^jzyB%k7Py%Z(hB*)5sq7DJWQDG(UI1GuA>J zGk(sJ3UTx54AbfI7I$=FNW#*c($c2kXD|@8 zM8ZU+dIM?>OeI?-4g1xv=wQqEGlQW|nyg7ohjBHEE0~;$suu%hFo103%Ge)*{^d8{ z-JnVjfMK_r09`GX1d#v6zzOckXl?D`I0ogS1n!(Bg$7J+ML>V$XpCZ#ZQs5ZZ$#M> z7#U6w_&0%N65Q!)l!^O}J;SD=B;N}SU_IX|k~!fV%QHE^*{o5_j@v9V4Q{3^^BldV!&UeQKJd*^jK@O*_Goa$wa7fHu_ zwIs}AEsAm=dtYNEr}9lw_0j;gb{TY4-TOM|oxZ*y5sQ$*Y%9TGMyvjhDCc6NgJlM?H%=Y(5dSd{9;%rN^vNnlMUHC>S?wk2jn33 zjlQ7J0-YU|u0ths6|Ak3)4STjhaLj#iDufvrKr~##nPCx?j6R>%=3xB?I6Cw{mIm_ z#s(Jz(j*?L$#O~-NoPGjKPgWpQ;KdMK7ubBm7+PSy@%Ki*eiuhVB=nbg4X%~<103t zY{F<48=F4s-f3{HFt_E==5G;1mlbFf zxvCjEQlvpOmeKp{HgXGGW;5j|2Eb^X8Jv0X_-;ECU%-&wL9YjENK7`$IOP1Fiw_BN zAS@X?4>AO#-nj7|wCmr&d`#;Zq<2#l6mpV7hD>>%$AY)!M{uKowvZC!8*YS=4EfMuKk%b zf~wBT%L`ux*sAaE?`Kp&WhW{5uep&_>(e+zV#sI@>IdgWfr1z7Ftp z<`8fK%7~I<__&zW-juN*V~em1+WPw|D6~U4E^bB;bY_L8=%xB+kq0AGV$CpmfHnIWOfjjI}BlTh>QJkmU82XEPA4y76!15I0xFT%Su=31%_X05RfXoPOT|zfrM1+i| z4ZjH4)|bUaFE+vNK|X{mVWmLx@2EW6n^KWTatS9_f9i@SPvn?VPnC zqxd>K&A`lDrz;2pl@z{3P!gsM*AfVcvu>HQhYSi12Y6Q`2y8@2b@UJ=9g6 zR)M2OMizx?f$#2X1=DVlaEFsSPYMar=i=)voA2b_{|Ra%>}!2kgHO%QGI4OYhkY#} zy8bPUlnM#p?%RTU=lzkp-%rWQ)Bood$^|E8gXR{??bw(*t!Q^) z&)}Bxe0?{gr>>Lq%}!p?jd|cSvs4dAzp4+OFX3O1f`i8EFVqIw+B~lbh#8pfz?|#l zFA>6EdkjO0Y67Rio039RL0SfeTNgXIL!BYYA<((E>=|#FiZ4r|N55)*g`1aFlHZ&N zj1RoNd-f4dY>osqANkJ0cuJDvn71NZov>Mbp>ei?y!1P>)zk%O$J!R+tL72;UIQSS$T$t|<9gA>4jg|Uv zn=FSQ0S4}AG*%pTFS&OVXxgkPw4*c0a_C$B0eQ5lgE3kaF@A#D}H|+|17IwkYQYv>SEW3t1v;AcmoiUi$UxIQJ-+ zYw&dsHD6s`wmG-sMh>Dpi7HaQa6xs=OnY+q=BN+%R zd)%nP-Pt3shOzZv@UGp>NFcZlVwb_h45s7M;|fC%kH+8@hrtDNN5EVqzn zlX362_PTluOkkz+rhMu;&yD{_jw~st{H!3XlPhad`|1M z8F#X}Y!Bg+;P}K>p48@^eu+25#m06C47XNGZo??!4ge~`m+ujBlGL;`!c%JN>D{xg z6WgDK)t{(wp|N}27`VC7uxt7yDe>*t>o;!_rZHIVapUzt(m~KMu)ouWOV^!j)PtKR3th~z6elIuY4%~HiB6aM_gYNaVT7H$IZE6 z85}Ck%|)|k&nBkef%F71Aq#|!*g;P8fWk`{edjE?*L*{jOC3}T`%_on{6h0eqc?p6 zCN)vxXHrNty=R{>xl(VET(NI8abT=C!87$;n`8V7k8#n-gWgWB(kF(<_uRA=I zYR35e_+VI)&NzDUUB1-p$r(eERfhV3{6l6rr&K zu;|9fu&@DA;QlCm?_b}m&N=-WamgP!QtkP^;tPRWw>6x4<(#>m_@>S22)s+wz+)Xd z$+d>nR8s=z@Ce^#R>({*dI)KJU|D=w**VY_@asDd%!Mb% zZ;g6qd-p>x(LTe`U=vb#Q}^$vM*zMAn$%%;3J&FJX)SwshmRL)p5T{xf6 zbSS~N@7|bI0tdUNtW~gI&t_q;j+G zmT8nWl-+RY_&`_uJ%Xg!A45)X##r~?i~AY7j;7^_d_`Nrw=~AL#4cL6^p7a~1?!6g z%OZ>_vj6N^JU92w#)A5lfyoCEE7%)+Tx>6M{u-QQ+0Daaci}1mli&|G43( zy4EWjHgz?PcAax) zFc2x4bV3uZ@+F4EQZiM9I^F#$teTNvD8b*(6av98ae4Vh$F4-YzK9K#?xohlsFsh4 ziFv@+OFat&V{JEpea;B5vJ9xaerpOAggT7Fu~8~Omq{Yjm_@zymS5BO@`<+Vtgf?>ZfC-^(vu@aEI)l!| zJD67*UFp64C3nx}`o!k$4!uL&lZ%ZZ0p}AAom(QyP)R2L;CS$oKdrJtcVuOyr@nq- zaiyR`AC@4AP5Le_PP9!hX2$(2qWOZ%cXA_$+U=0&0|nb-hMqmgsjwncb+0a$Qi@j+ z?m=GWQqT-AUKJJ5xLeYbKA9HAV~-@z z(oLh17Hr;-93&XUkp7Yxv`i6;`-U=@CSxt z0F9>~Oh;h(hbafFomMr@IL>__*_Z4vkw|mc{QbF7R=c?g@F+m#7on9rw5Cky2kz9> zT}1hU-Byc?4F_wke6MDM!>5*{b?t|b)WkpXzkHRU_0{0p6+L2p1N(UG8lU#a;yN;Zelf4>QOv^>>vq z%%>d<=z^5&ZXW&trtx9K;3m?cvjln=`RoB!a*_L8ot+@oDTs-EMa9x?EcT3P6<+~| z46nVt0W)`Q9@8Zt`9megd!8u&^*0#83oR80=I@ z+gmjU++Wd3J0R%r8WRQH!Qr8+%LSh5ei;vtuM!->u?bNt`~^Lx-H_+W@kHYeLN5$D zCzrmyK6S-zR_Vt=9qH|(8j(D)>xik-zXZ-L1;eogm+un~JRO~pIfy(11Xj)ZgfjP< z5OORyUpMyd;)lDd=u|x0>3a^b>*CZZj4-OdjTF6rD$ArG@10V=0Ij8@4%4fio&_vc zF5R=+%Zr~$9GOh$eXH1a#KuHcVZu+d<+Fn8L&4nP%BP>>ojSPzP@anak2^ZH7XxD& z_nY+(%H%PNH!O6n0}n7hQbtRz=!0|H(()HUP|i_V`7tsxxm&xk?`5Z2>Q+l(eWcTq zVEGiiHBLImeeBp3Kn4S0u{-4MKl5+PIN*#j&@0rt6OV;Cosp7mSJ^rk4S~27#vAs* z>n_(s4@M*@N!DT52s{U;LnuPc8JU<)+>|$a{;3$p6vP<N@#_ zP%GMsbJQi?mr*u;PpCn$b_Ywd_Hsm8x&CH@;j}z4!+-vPM(jH1h?ptorP)jnpSld~ zsvpBIo1+>^$;r9f=}#hPSnH7L(NkJza%|jR_g#o)qrkEEknnurTg-gG;Wm0I#i12Q z0NjVC;vstV^YxvMe`i?xo+AC$_NOC1<5hQ+pAgw^;WAd}$#*BgW905^m(2I)K6pU< zeh4IMfGp)MgH#A0negez_Z0D}37^UJlq)~Oqr-hLT|0r3^V#KQ2ai{CiP6eRsa+zX zQEYV<#o22Sehf>d)iGpWWqV7PeYN8A)YPX}kCIl72Y{rozP3g_V0vx) zBZ$Zsyu2pkvE@-Xh~g{T;!~0T`P43hJ&`tS(kJ3AUcTUZDkYw&mhfK0xDSjK%xsI7 zgt?pt5T9HlcE2(G(`;@w$4?XIes=!W>3*L67Uz37U-gP`eCXcLd?L@A%wEOI#=8ab}`P>O1p&-oabt(7ps? zT!Vbwcf{Y}h6*A-7fA0PtRPt(k+a6ct9O7O;0SCIM~_?V`MxyL5dsNxLCk7A)(5E6 z*YD&wo>aScJ1Lo-IyH`pRl zBnc1@RtH~eNJNk=AGuyiJ`uI(yKAsHgH7gWe{vnh3pc8>1xG?|pd){9zb+i;2g%0o z(#W=>5a_NQ-wBe|pZA`RZZ|FM2wK%!CtHeHYUq|xWXz=rBygX-crq&1i2k!;*Y1#f z7JEr!kL>FhU*; zIG&Itvs|9|dVO$BXggEQDA1Jy!SCV{zKJ*FzGP)0rFu1H(o9*W>%FuLs{N^7Zl)D}Y zjYaScepg9l5c08{{P^(*h_~*O0&BMiOb6XkNB!#DUdNgZf(^?ZXn!}T0IAg)&6d8F z*5d)7Z<)o{Bcco^UI?x8R-kZ?}WvNFV5(X-~4ev z@YFfiv#y6>ak}wcT^uf#_T4W0fhW@88>Uk|$s71F?#y{yC zjn7tUUe$2a3+I!Qlj~d72|Y(?!Np#hJkO$-r0Wci6#h;UTJ@7;lZ^%M$r-%_23Z(> z>%SyDnbmh)|MIL6T;yEGI!Id!#Pr`S1p z(}}gZRj$16KTBAVaP#@yr=MjxH;OL!M^8Txs3{Sc9(^HS>(4GLHRCq*FnO1c5Q*#O znaQ|MRI1HD&mPyMkgLAs*5;RtaAepDcRc+I#X4~AqC$ZUuHYAUj@Of508fl{+pp-4 z47cYP8M+=}{KkOd7)x5SLJXM|t>yQ{k+iQ<5om$(S#V*_N$AHk-JQa6tBwBk1;f*P zS#ASGq^389+DUcCy>Yy8ga>{rVk}GH*V8|+&-tup2zP*k$FY#&k=XkoHzpXi?muVl zP2Lq1JWb2C^0`gbf{X8UG(Ay3DrPj&y+M`@YL3IsmGG)W{=3*;h_|M+(WO9Fj2J0PN>Jkw_Gf+a#JS3PcjmL9miC)uJ{u#an$b0be z7tNuoj=WOjh@9_t?D@|DE_++jI@@ZJ*e$no0U%#Z)1r87Q>I`Fw4aqZusqazx9pg;GP zpcpj?Yx^+RgfT{XKXrJj#OLI#$at7%rrPAHw!*PDp`!8&)dE0a&x8|El%;pmj`TVrkX{f%1w?p0VT4c1O>Yo7zFU|AlZYFo< zi0`~;C%-<~y1!Rxh^d4l{HXz->;v0b+YO$RT1?`25%`b2B+CIn`oAT7pcwWBCV9UcfXz~ z>-@qbEGT9wWu8m-yGTK#Nd}$K_6#d#gMM50r)?0Tc^EzVUv#~9Jl22zJ{%!?@9dSG zQ!-MrS1MAr?3oZsL&+XxkC3uUg{;g{#+g~sBorBGm<^QjJ5F8K@4oNv_i_Jm{c(LB z;ymB)*Xucs=W!g*3+I(IKpjXnd_a((y!{f(>(;nU<$p!Ao*UB%IbwwQzyUD9h8}P4 zl;)-5H97Uk{-XWdfhQNqHs8ROgmuqtW`Zm-OI!iR1XCnl=8h2Z2Zx3rR4#Cf_HKWb z|3)+ zU%6A5&@bzHx683X{s%HtbyzOdE&178;q$NUEDl^W5U$Z;SMzwvSFABeq$;GS;B~u3 zM$|pPa8vyJ6tnMPow`I)SE=h0#=ymO1tWq~Hi`P{UFS_G?la36&HWIWIMX1y?=z{g z`|$gf{S`i~mN{&)bu=Wb&#zry&I{poi#~3ZwG=EguX+FSUG878?>P>bRyen%87_ZE ze={EI88&WYdT>qo?74cl!vDuveYLngm(UySQ5uUwqO;3O&-4>uLj|-yB7%%PLe@J(3!T(VT z_;4n5<1XMNq$WBS8eswN*KK(r+R^z!auN9xsRbP0A*f5Sm=FnP6ggNpO4F6cJad_w z5MF);#gyI4(zvco&Bz+D-r}o2E$?~1YB-@su~8(QVD0yNy#$IOcIH%Z%8>+5&L&-a zJT?0BE~y$*C+BMdD89M&mx(2j)6vj`ZPKdi;_;Lr@ehy8&lI{J&uz$Qnjpk6Y7;@Mi4&KVHSv>(%vtbOWgT$` zL9NWa+`c*U)(Yd~kFJw5@~I;b86g6Bijz~vZkLzW4c8?M)as~=RRt~N9$h$fmLqM` zUJp{k%{3p+9f-XPBbt&Fdt&J;S$KKlAF(yV`a<(qSgpx2?U9L}@$7*}i?OxVbQPLF z=Ux|zN3*{e{GH{xnW5+%H`^0YR@=#k$ve6@N5a3)YHk@nUYm0i1495Iowhs{6?R7N zWWZ>^9Y^JWUv$+%^Rfa4uY33Ija7UiI~Lki-L1@jR_cM^`+alrMoSC3a=%IP_<(ft zB8P9IG%x$|*K;g8?@81!xdcR7#1rq6WQ`L`pn!)AbgjMaL zYyNL^;9%%52}Vz|UMqQ&R^Tfs=kk5)`P40W?4J+5VtXT7NMR?W6s@=4E~p{dvb(<` zc5rYIK#gcP$YSzUhX1abdQ@pmCI&g81Xnp5oI-K8^HUVJvoPrxxRb?Rm=#p-L)3kn zn5Qf%>H^n6!;dHDUE0cr`dMQ{B1WmfnGkzL8dfGoMDJ2mOua3}p7!pKSc)Ru5tD#( zmmX)i=H58^vLW#ih3cD~^MO;CBBE85IHsl1q1>Jh_U55$;WI+NKK;3lIcdsMk<*IK zN)PHEimNT?w)gG1L1zDLVL|in(%#v(b3;X~4 z!}{qsE!{xyX4SHjZ8$ZUQ#qDCXlTCCM4{T#vasq!+XJ<5hfQrUJ@K%11^p+}&D0%( zWqeO0!WDmVs$QO49s2O$1D5?9zTu_biC;g^^!yYPW0;Os<=8dP)7^el+gv(dkXTb4 zS<#P2sLaRe>n% zDhJjOI(s)co5C-r^vQPWYHQ8Un}BV8p5BbBRP4d|3*&8+u|jV~Fd1ZG(5M!E(AoX; z>Cffm&frq@9<9_E=Q1!s>lJljWTonV(MQx*&-0*j7`|HawsEml-#r%?1KPKa&2~|R z(J#FGzn@~2aPQxzFw{pkaZC*yYE8{e#|BvcpDy(18;-!rW0yC&)vm9}l$D&iDjYkn zE!b}M-KMb7O@t}hS#D_2NKsnkIEEs4l~g@mrJ3pDr^t&oT71djlcDU#jJ(4)eh+#& zj3dghQppS8MVa2do>S^!0UIYG@{7&pjj9$*H~(MIr?PF`+G|s*`@gV)M)(_m`SzL> zG_OZ#_dMfvHt;VWZm8e{Xnx4tTy<~C6y-c-b`0g^nv)i%zDRDQvd85R4lgl z@Bw9T&Cf54X%&{M@~kZ{E!n`a*|rfld(iN+XG!#;M6a1^POVlOPjjpZyWO+5m#RYf z_G+U9GfwQty@y>S+^MZLwH>nYXW$hU%ksP538c?Y((?k8q5;v{&!XXtWk9v6hW`OH z{@gA%k7p$5(2aBdLSV8hF@uOfkXlx8zArtbv!hNIJEBOBvX&Fku zw-FuXK`eWf^~0Elf#+AMNHnk;X-4fB%S{nIHpL&Eju z8o>i#+|StTVPB#U%dWmM1&AN7pLwU^a1Vx<%J3w9hn~V0%{PVDkK^<^9Z`XP&021crS7;ysD!9gp8(rTc{*Pv_?WZWx2l~#K z1T%*F{N%5+cA=0<@p#moQ+QhVOee}Hi_6{sk?T2dTYwDptoMNxEdY%gPDJvsRCWaaCpj8=qo#zJqP=$rj_1uQ9dfhC-saq3+QiUV$VEW&=HN|=?R##tNKb3e@l^A&+L6FaB z`_YW_^uwm6nneC_Iam8B>TO2XP+LAq{z6;3aT5BlCIvC}_47(6o%;mDA06MDU?B?0 zIH%46Myc8HCFO^o^?w!rV3mP9Zob6&)}SLi^9I`4L4P>*%V>$#2q-vix=;g7jz|h7 z9Z+ZO-DW$X>tRAoZy8Q;~2LRPL?2 zch8M>ADI+@OVNE9<6n-VUH@NV_-)ftcdzXGxJ@Fy`=pVYs%mAk>}Q<=q^^(@h-pCK zD*Qr#zW-vcS8`|Hm76URe3(lmeovm91U{$iS$RuuyXO*=W{+%7HsINTnAH#!Elsy^ zEWubji$W}j%g+l!u=HaI#`S5g^I^3qKfZyiTa9URtRplBD`yqa(#$+Bp)1_y9ros* zWW9y+)E{P}mOZp|yJ@Op1@(g~d=$l~-`)3qB^?~R47*UYXQ@!F>n5M03F7nUm0#Nz zn~-p?rbZ^Xyrp{MWSY)5Vct;ua1k@?$-gT|C0z?UeP>4ig}3kXO0E5W0dzrFuA2Fd z;}{LnXR&}Pf;v1%`|U$&t1a0o1vdIkKCJcx4E|{j##kgx$i~;{?d`S23~Sgcg1QMA zcO+F}p=*P>KM7bP?Ny$&DbL~rO8xH|OpK!)bi$_qpqBCb?e7f0;*agP_>Zrqu8A=n zC_-)WRnx3Ga=Sd$zCO`AB$O!s`N>v@6m|4{HGg+)qQ9L5+hXT!GRf~$o>ADeC6*Xh2 z5%v6D_G5`>>)Dt$VtbFjeUYyu3l%;0Mbl_W3B>}%%qno`g`KywmRw6_uYFPbjID%O zx0)e}fA?vH^33Gqiwzvd@59md9pkvRxA$kDxX}RK%IF$-%e|&H(BMz=^GQl+b4M|H zA-|$`&i2NC!Eanu=})z~r@|Zjz~u|_muEi?M!9%u!vH0* z6bdEKE@kDPfd56R-XX=C!d`-TJ5r36g5k-Zu#Fn@?awE(=gpCx23=zJo;@HTn4HyB zBf{8J?8{;Jx4(Jy>Ib08N}s8+OO&8?Qb3mtN@` zD^g>&Q#bs|4>mpc_8A-22fXoc7v9+&zy%_cn8$lex=0&bP`h;$)JhyN@pJ?54Sbo| zOXSj<1lVi*ZE5};!x3ZpzP;TAJjSNwU*((|l?s^DflHG{O_#PG1E0X8@ikIJSk*@I z;tsGECrE_N2n|VyP!cC^oE5IzS$}+(ia3IA1;Rz6{K-!boFRC)CNGna`v-b+z1$9| zX#jR4?ka2^m-+SPxe+LJzhTE^n5qBh&DZ}zAu5)xXU}dnV+~jrc~(F);` z{89@KvH2$Dc+q2R5f|qzJyncaBph}(}2W)+8ZZ6dNMFIJx$g60352uh&|>1n%#k7c23Uc_PS%9cmMN=$$o_S z4A{rgU3GxwJ??XQUY;ONQuGz<>8TNo8S@wXZbB7b=kZM7P!p!XB&*q3_ArB1!R? z(iU$KEN0K z<89Rm$f1oA3Adcvx->#)l9Yma`G(lcOngW5;fA}1hgO3KR)ts0rZAJ#TAv}sh6Z1G zi4E|gG|1jafG#eC$BgbCDrOzOOVk-_y$*l1JJ_WRK@64)KU?i2q23g`DbEgGd&m(0 zlRMwizz5G|vuO$ zn)Q|~wjf96Bq*ZT>UpZYev|32rg#QNwL={vQg zslp5IHTkyUWkKsP?jVZa0D)3Ceq3M@OPZAp|JeWOp5*B>$Y4QSHK~(E_XkIzkD?~Z z>H+v>x!*quqb+QW-tq5sm>j1Dd%CuhIn3%GJdfL53RPS5P7EFHQyAz^tQXYLCq_F&?kKc&(CC0rry=XJg3_FzdF}E-!(COHf#<9@*UFkjLpp3>ljnHJUI)Aq|K?l!q03B=WmKSyO^9> zr18v6N@8L(JO%Q_pkuPRNn|@vD(uL8-aI3J#H83Kd0%89MnC$OK}WV3T}_kxA9Yfl z=K#4D?I=I!l3>aFyWKr8Waju4=*jhy1oltczo82N(} zlYVpgs5;4=5^A+><=ZJdFV%?fR{4dbg2fzcisywX7#r*6?jJ96Ce_F{W%J{pgLC~j zL4r%jyV2fYNjOL-95>Ixh8F|}Av?Vwqo$e#eb22k`~K$x+J)-x&aai#RsKC^)1}_< z>iBwmJ>Lg*gfKGNKWHX)41g_|C6^fFj6#)0^|TXWQ_GpI%cFYR}{37wI$RWA8xu~38j4uN90h{&r^i{u7{&__#?Q5cIC1xkLwqvNQyLl5C zlK4=Si-C{NSF|facab^J!F(5I- zXHswe&awrlwQH+VwK^t`H8p{_h|u&Z`;NqNYNzILxER>?|Mh&JxrHS%K;Mw#(CLm! z(>+GlyR(ocN4WhW1BEt^vT%zCpk$5!ABIDS$a9FN3|9~~~wqP%aN4|yB)*{cG(NDGm44yKC^*`P|4mwdU+ zBi5eJAy_Q!@y1s`SsdY)JcngotFU80Uhcc5er27Jee-^;vzIgv&TH1d$v8ALl;T8? zp(x!X>wt(~hRZ7e<2nale((g1>!UzN$Kt?3TZ!tp&cadjM0FT3(@}0exnJSYZ}UTk z2H&vyr;yBXQ@&BCdKwzWzT2m_K|d&QHqJzAwlmJWwSD{!b1Uw;raXy{Jo;-h6}{$b z?LW-7Sb4sZ3A(V!8VR^`${hRkceXVQ3MY+J`_ zWx~xz7|sBSdnt1Rio2L4Q0;V5Zz|?T=%b$Q*pn~Z-ToF1JIo^7@k~}!jC|ZEa_*hH zHsas7EeQj(B!IXP#1K(py$*xyk=eZ9*#je5tA zr-vVfOa2f|ARK#Hx(F-(rr~_8&B{h^s8r)o5~qgOM}tEl``_Q%{YaJWNh_nUySf-C zW%Nd`hVOD?d3Jib?ykMUuglom-XZb$?qYgCaL3f%dS6sN=|PaF{7>gVbxPwfWyn(T zyWZTa{#K{@Sl2AY<3dt{;MjFCV{eF-`?($S(ATMw*22T0$v_tvQ~;!dwJ_9Pz{>&8 zTbEF9zW)Q$_Sc=5-UPXr0I_blK3#g^_Y%i9oT8QZA^XT&lSa4J;R3fW=);Ds{r*3H zr6Y@?Fv4}%F0fK3v><}|vK3F1>Sspdg7`B(zgic6EaOFq9q^~B)JT6`Tucn`hgoW8 zla|uZE)GC++Z_lFEg{{;lfbDyzb@}hx6LG#G+3^VFX*1&-%Qf(ViJ~}^RK8Q9^NSG z`eg$vMVY&Mdcq5}-sWDrW=%;?OZ$9Q=4L$P&_>do6uvj2AQKv22ctMJFp#t=8WmWI z$vS>H@__p>@1%{tP1@=Hs>1&2oJdYRMQ@t7aBtVazwqo@TO3M>xNFL``}NGlL1A)W z?yKxSiBWVF9W4*kNmoqXizx7fJcEeqYx`Yt29jvb%7Oq@?Zo7yZZM?Md*KptV`O&- zjJaS4gT^l;j0}3Qg(@y;6LA7z5mnjR8|g{~lC-H;8a1Q}$bUw`km2GldfphJA89&C z7q<>}(+YW5zIVYPg4~`Wg5l>}Sw^g@kFEPMO}yN~LsXhbg^CxH`#HMC3C7I0kUKZmn#=*go7F>r)GB?H+D@ z*!|?G*FAg>gq-LbadTM1prNGnU8ian?8Ha$29++8ej|t3-7NP!vq6|$M;12p4LQvM zQUDw4m+8Ty`!`+r3@JU5&=6Q%{+DhE{eXPMNzUSu8^VMUr{4$UrVco^F6~m!zTk~;}CKm+?vO-Dw&2)bUaUI`> zcy8`1g6TipO3W2A4TVa-!l6mD?F7Zi6@#%9&=yXm3T;p^*%P__oSh*!^W_& zO#~rwO&!9Gs&6hiC-j{#jHhC>MTw7(_(fVGAha+`m3pg7Dx)MmCqxeY<+dtKm-4o$ zsbx#4h<28~C9zycbqesC4rQV#9#MUfKR650Ys`_{)Pm~%lee#6f zp)&-DJ6UiGPLFgxgh~|qT#SODp-ME(#jk?_I$jXChYOVCT2mh(y96Y2;?ya9tBY2b zzXj^Vd-+_J%JzbR*4%1=wOTW`D^Gl*ODChU4A(MY-y${uL2wf@2cIDt2R?IOzJ3SX z!rBDVG3wU3h`l|OqcrsNyRj<8LDmI!t0SFa%=}7kF1MxbPEnwdJCR*ueEUvT?Z<6c zYYJuuH%h6F^L>Z-ut0E@W|SWkT_9`O0iwy1T24R%KG0Ew_w)fa2#<(B>AM$42k~l= zNDuFsL;aQq6nS-x5IAe)mEp6TDjq_mnlRYX@k=GznKT@K``RzaWO>XY`v#hSPqzRh^sqd%6HW1^%iNhW1`cJH2% z^9S`FgKimD8w?^y(tjJ9oF%Dz)H0fTGLQ73ibbnBVDCEPX_+0Mm)}@(@19=mGcIb1 zDU#_TUc9}N?K#+N!@MdgWB(Y5D}CUAgvCrO>;%x(Z1=dHNJg>B-DSm23n7 zlPrY-d>{DZfJ#4gDS;#%cC_AreL#4h!5Z|NX5BxK8E{v9%DQMNB7v!o-YQ42N&?zm z2LQc>@ER*ZSs1>dtU$avihZtVIv^D~4)=xP;>hx{Tnw^SfBk9;yCP>Rk?lfG@t@BR zSlC~^>C5!A1;o|qS9DOC&Iod4QRUbQ3g%%Gl)WO#zF0md*l`Sldtk(GDE7hlE6IS* zJ61F0HOZL2w3K?gb+s$WtH7AQem8RkhE5`?{=vZq4<1yRaQ*QwxJ%f9s6hyN18z0+ z^(JSmp=MX|dOn%AzP8Olh&g@B(juIfU;zR|=c-k*Z(2dCDPb4o5AY%lfBwNF1{E9g z1aPkWUnLK{j!boxvhPH{;Nv;k7fF}F;ah7ejobGws#T}K8&15yp@oPU$1Xh zW)pc_ONF57`79zld`8~R_|PdG4-5-wn^h^p6+K_w<}j)+NbM+cc5yj*t{p|b;m%4d zaGTV}tF+^PVAm3I1~xeUK*Kypla}quGXI{0JFLzzmmMuPzsdOIe9xwVuxr;w0aLG% zhdna%yu1psCvX@o9;8AnDcSF9e@;y4EBdxzBTXBs$ur8u`(eqOTCJ)n{-3l7e)Ub0 zZ0%swzy+?k%unMIOeo3I3gV3b`)yMppwaGni$3hpoHhY&eBCyZ5QF!1buE1V9@z!1 z<`7W7ssE&Vh=akrPVmu@Dab16{ju=BAAtxqVkZi3=ytU z>kXNmpeWXW<%lOLU7W=I=LRkR`?-({u$#=NE+t7+X1jew3^rtt=D3I&5@37Y7Y46X zP-8dH+^x8XfB*i)eD*8$kgFdTQg`UHT|Hs+Q-cH(j%60Rd<5cUqPIWH`T3MTC5N_| zS<2i5Q;(Db0p90Edzj|8;NJ#>-F1NPOq6(67V(Mi@C5b9_<2hIhq2E1^;=3`{=H&N3v42c|C)IWYL5 zs&1nUj~5~k%%+ZiS>j-OrwoXuIzgfdZ>XeqU)ac&gvQi3a!PW#uzlnw>}<2qr+NT?yT!2is|gl*8OK-yM(Q zR}a6ve>I+_5$ytD2n$WV;HZ6C+S>rrWatbtb~B1GmyV-S!+8|uS4ZOD;8!P?!?VX= zG$ku-c4Wj(=S(nC@P_14(@|qE@fy(ZB_es)6zQi53ui*!AT2E|FK@U1o0u2+w-J>L z0_Ox>-+q|;;mH(IPH*OQ{p0i&ZeMs|dYy^+ZTP36qM}|44XA-mJrSh+8tr^=M*u{5 z)m+w`S(+HhBf-4dP3dGdn8@#2EfS`A4o?N!5+S!ro<-QeOKb{SRmTy8;dGbnlZ4X} zZ?sE8p1;<{=&S+CCJ08terGFOZPIk4>9I6%)%hOK)76!wdcqk*#Gu)?uOh|IB0sGynm!9bhH`+sf4+?+MHyhtuz7;kqM?iw*zN@ygr(^?g^4Svg6&l{@+s zjs$$K^RrYF0QDj3W9|Gvm1yMw(%%~i8f}3s{HWImrr|JOQ7aOcv?Zief&uC8J#(1p zAXBscPk2LSpBMdIcl|h|dsNMaAA4^&bC3+}Fn5FZ*f=zF;HmWCWn1XrEfT{_Q)l5= zb^6q&rFy*P?ZIa@)qv{yeSV1?dLEySl3nZk8S7PKTj%|0ZoCB#`mbB~ z^5Jx6jEYX+sv_YbA{M$BIR3%+M7<2T(4HZ1sr#>WGi1NSi&HHU@4u6UcX?IG?U0K> zOl2f>X>q~Bg~-PJSJg$x_0Iog4v#nOL(WHly9+u)TwEM}pQ*K^0|7$gnYaC4cTA^C zncwKA<QCwZ`mAcl(UVzowmcZeGFOF6RCA|3slTZr*HeZa#PREOJbI zBEQyDVF;0)k?~!v7uyh)R66*|2`@0eduW5~?!c>rxn@TxLm5EfvdN2a~H6_yR0&Uu%Q*N2<`2`!6Gbq9|ir$1Ov961VUW<7R&hy%N9@W^SjtemV_ z{v3MuUT}=U_{U*GLSR4uL|+z=p}~d_L%i5#j`-^67U$^5NHEwFp5u`^?@5S79WYa| z<|22R*ta`q+as1&t5y>8nh5C)R!t(Qmoz?*5GkFYh^MSYNY9gYWNXNUxBntK$l)rA?}SVbFC z$#(DO#WbOk5z3h?f^haAb_anmyR;>{{jTOT@NPC%*8HV@yY%}o@6GT5ul^~+d&Zqy zi4u--MBUo3yPzUjF&?OU!`_%!sc*!e@v@wc^32Fz;c6Z-QayThY;afUEIoM`E|8`M|7UhY`r4Kwx9y@9|9D+YS<==G} z=*oiNuGrpv+LzavU%(tGB?+Lg+QMWmS z6DPP#oYlOp1n*Kka`(u4Gs(DT+PbR5m203#z$(aC=c==_bNrl2$WPcXg#J|y5F+(feoEZck25QtaKtIgsk*0ZQZt#g*Oqt@5{tQ#MST@W6MhdgqB)pp}>~V3JL*;7%P>|E7)3r zZCa;sE29KothmI}sPIjPy;nrha{Ar}->47QbR079F%Q{o`1z*0T!t%I zp{upUyfQ@hK@8Ci9@0T2tL_g`N31)or zOEV-eyrmPN`1G|hHgM?0p-rJ|MCJ?!R6Qsw`W@!jFPt-eWb6yE4$fF?PZB2M*RM1F zFpyx3%6p9%KXHMac&N`I^bdywnP44~2-=^zb}?C6Jt-{*0y6Kj*Xmz}>*vu`tUf@c z>vY!pSWuozi{;#T$>~~-9SP!xR@kn)ERirEVPUe{6h^Ge56IrSmSsV+?yR<-Fs@eZ zJn15W>_FC7uslk2fN5HPXX#69)0ia2yBE{>&%z>>P5$;41RghlK$lK0;AwHhn!g3~t#EU{TP z9~(N2m%k2~bHAGab7Usa)-PD8$-kS0Bj$8L{I)6hZ4bE) zyuedg;TtX(77YB>ST1pntFg|X%{b>vQk)?VZ%Sq+M$%h8zFkoxS;1!Kh7}-f@G8X~ z*Jh>^j&{C|Q~~95Esb1VSr)P;2AF)kokog8u`%**zXtL8VMg8BiE4!Naqq+dZ1US0 z2O5Ry^+7Zo*kr0Ny1cUJ(o#I0;7l@)>3`33`C_!T_X!CU2rTpQ+KV3A4g|ApW(iUZ z%LWUQ$6nq3fidnkwK^U5zJonc-^nJZ)KrhG{|^0gZCBMYonWj<%jHJGUT92pM|$+% z=3mns`#LqX6W^Fry!4O^B<8O~C}fA2q=l?bUCEF>@z6CW}Z$lcpVKUL$zp? zcs1{rl4i0yng6z5<(!YvUi^p~x|(qSkWG?*(k!fU^KKu$)uwzrA>nZbyfa+_!4AP` zonl;92SJU2mezRx{+$+95z0*|Av$S5dV8_i8=*#a3%SSFdR`?#k_`{llUtF>X7IbM zyLxr&eVZ1sAb(JlNTmyo^7YMSHuq?Gd(NtYk|mAlsJJ+#!SpjSp>1GvEh}N)Q4RVQ zF5*%I6LVZq$zhoR8Fos=_#qqv@CXkz;hwC$z4?<*#M-eqE4o@Cm}Oo2z7iXNESSyV ztHBZ3DKFcCJ^pzTQW|WAh569eq3o3y&bV?VCO_l&TV5C9;cqTBbTBkBliG>#h-I0T z@H?8Q56|LToKJmv9`#_BMdB1m2>d;LTNPcYhii9AaHN@jSxZmG>%uekaCb*B831$Ag%0!% zI4&h0PDF(pI1v7_xVa`!DHp1Qge_}855FY;ff%JQV{8RS?(dG{<=ZHI*! zr&UwXtx0lelpqaXG5SmgOn(7pg2NfWS2$d*);+FvmNpJQWb!2d#p0QMd0)v4^v-`8_4_v!h>%5MoJHKTt$$Cv$ce^d8no`%?%CSxC zSNx~h*=ty|`UyzVw-@q4WA}!Y_$ZAD$K&t^3VrU$ikQ=V=cs{I3A*)kd_6_M*(5%- zLs@H2Zb-`1@+;OACL0WSTkGE7oRN`uf9wGw0ZG+9{0fA$bMi&BGKhe)vQhW2Tt2mm zBWib3ywP^)PCdQawOPF>ztP4E=gfv4AA@M_v)c4w1C=}LRoV7#_KZ(Wm$%Uut;gDOla6HonHCk&L2Pgm?}f574D9oFKE=@P`k zMVhwXjk)!FpT%9G{a$8j#_H;$C!C~admau}gM*c4A)}(Q>kIOlWaZ!}p|Trf%eFyy z@^PI6v+&!1f#6~@9KP0xTn-Cr%EVj_Y2(Dp<&u*GuRF;P!pMP55Vo?9{n0Z;8%dVhLp3mZ3 z{!VtiBtO5wdUzuG`vZ~A!^0!f@8hj^w0%|uZPFXx*2Q-8o`>b=UM01HJ6G?Vz0n;A zoN;W-@n--mI4)qOgPJ7t^y$+B;Y5AX1H1u;HmPY+xvAv&Xo*GkB|41C+*v}McGSIO z(mMz*FFf0Iaac&g zUWy!W_V{_O(9m^~v1O%Cyq@wO_O>!`_` zxQ1&t&tGaGGEYWWML`x3lB7FhGU|!T;pX`&Y&WD5GjOo!0EXW zHP6#O1BiBsgozEo`YlgK$!9RR*NvT}3ntPE`*&I8yFVYEV>isrGpy886V zA|hEzeiS8s%(tJji+6`Ry^KyJk&NN(r)&S|HGD=ISe(7@k7aC}6O3H6`BERD{}T>weCXflU}obdTt^0aR3YjhSuH?rc$I#E_K?g-5ujUS|x+ zChNUkL_ewaRd}x$43krurE<_txr@HJf>UKlHV`Ck1{gVDXo3=N73^aFILYz z05YA$HyoKpS)XVv6h!uP6mN7;@hLJY76vsGloHxYO)t~D05~cq+et0}TlQijwmI3? zI#*8$y?^vz0kVkd_8tgTTR`1S zE7tr=M{L{+@oNFldrTpep15tOnT`?5N-9XKthtn@a~{jw3|(97L{Z13$dHo_OS{Bp zgdxRsvW-jbct=2PPXgDax&Ob8M&8iAZ#!p#`hoqjHl~?zs-Sh&`J{Dqbvcr>;JrU` z?u!(ccZJR;MDqS+eLX#-bw9XY`tz?W(d#~0k-P6; z^pJ}+$+*dLKxBzPMv;<120^roSIEx$F4HcBnN|D9-rPfa55MZ1e24NEiKl}vEg($x z05g@Hy?akDjA3#^*E@8bRr-dUjeErFoPs|cTLuajRwY``=OCj7b3T*{VvOR5Z{1uH zXbaNboIGoB7nnosa?G^0lsvX(U7~}xU9P=_N|Gz6Qu|drbLS$RL{)BWuR4G3?KijQ zCDS`R60ROe##9-iDX$sOkxT~uQ0c~arjC0rO4J`c_8Z{(ild&UK0)qx7De0L^|fc~ zx?+s0&A>~${lr3(w^Uqy_;BxV_?8=gl(wy&t!1BDi?&T!6IT=dB+(gCr9VCK;z2k2P*oIe%yqiPR#0qDcHrEkm*n_*P%Ze3dXQ zz{oA?B13zI!nWM%mh)%gY&hfJAAX@x&JrFsX;vSHuK1KN$t-RW6S7so&ztmv*i6eI4G!v#yZvGa3m^GYe!Qg<^bHkO@LKUNyiS>Gt=4aK7y6aI*t2JtU`Z<0ZcGp6iae9_g z9`!7$Mp7bW;8i;P>$?=|N-MR!wZ?(-041WPe3I0Nkq(VA%k0CtylNvCSY+z@%*@Ob zD67lM%4Gje3qM2w*j8OHao*&wn+O5-0Ynm^Dxj3e99wG>+0)0aejv$>1ewVVxTBvc zUy8b1eqXNNwAGwBaQ|XE)82eDjNunyheAC6Q*T;r`rOpJ80Q1FgcnvKQG3VLB%WdR zLjq8Ql9|wn=8Ha#|1>@>oH?OzGpkZ1QvJ)lExM26;}l{;n|7j+L41K{>3~Oy*Anp- z;mZ?A31{ySyR(+S@Lv6RtG;%jQO{R1eaT+o5b9VIch+r{6o(scYyzX)4s{iP^Cbfy9)Hc3ew*i4{y(4^wA zJtMOQoE!61Pr1545GJ3WUV0-Ky2kQK6rLy=QsLVVU-oNR)t7WpaebE&%s;{aJD%mg z9Lndu<`ivZKKtx_U8&hVm6*4$qEg$M1HwRFZQImg$7m-{d)ZOg^-i*YQ`I@Lz<96z zw_dEe4ZN|BB}oK|@Wu8pp^uMLBcHoH;34W-C3w^E>oSu}VP9&vPESwc^#{TPF{B$~ z(}{FbY@KZxgnLx6fd?QYaLsniS?X?-Lb|G&5uNb$2s_ulWcCfF4o8q5v&{QG{K}%b zQ`cugz!reWh1~7$?^tgCtoT^d=<^f0Vd6FA`=1W>ULlL+b>xu*Ehpc4_mpUl!i9&E zA3w&-EBb3pBemz>USc9J1k^2AJeu0c=!S7^oJ{w}-QcxAE79QmaBYb$N8C=l)?=a9 z^d6LaCsJ11PH9#iN&7=k$s6{r4o*2nr&3Vd_&2M8xG>Rg_-NtR^1L6P9JZWXRWZzZ z0rvKwyQ5>inlL9jn+9)%aQ*vDenpt9l+ouJ%n9XI!Q8bQ0$_vLm=7Y3i|SFGI=E7kuxg*awAXhj`DVipke!!0R!jLjrapWq{B4&Z>>~4X%bP9tc#jYJGSpHm@X^)QCjv?=P)s&7 zq*5L?FeQvMAXkfM12$+kfHZLd=pu(&#Vm`@tC6g{bh=NQA2S5_-~PM2{!9I&^E{UZ zb9M+%pv#4RpGRV)WK`&#NQ-BTu@Le+rdY+){o7lZ7_@EDu8a0)o_OuA8O{8na{s}D z&wwl{4s=)+{dyE9b2jTe{XNL*wTlv&$v6*G?PmHwU=N`8v*WP5P-m(#9e`b%Ru z`K^whd01J)=e2+LB*vwx9;BY~W}udtnz#dUBW?59l?CA`X2pA&4ulh|sx{>0>MU;w znM@}yhE(oXcRYYIG2g@U`gnFWY0P3~YErO`xurM%M?(JJ1$K3vJuFX6a#d4^Zxzm; z&FEk!nf7{0C)k^HTo0jSzV0GYXmIDTvK%tdDXK-)ip{w}oI^q*H{>6A-X02&0+Bs` zX6x(_CfWzHO=<1c?za4jSDsC(Dz`aicjm$c4dume12X|J>-<@|5KxbJyF~5uoc+SP zr!y4Nnb9CMvV- zx0Qbj#|oLzb&WH>lO%QAM;DYfD(hXlcJbD}>i5qR;*))do?+oKZSRnPi_F?)t134M z$7T}(Hh$1W)y-U0kCi=n{^CzJ509FV5UDaghnT>8zS3>y)fr>!zy#rwAU~$l_UaW! z1zS2xy`Y4iU(6%$^hoSEjCNsLhpS7OqrF6YrXF=GIG-baa|l z@8^uaNE|=%#Qtzk$}LntAdBs{l4f1FKenl6?c&9Y5WjF_*6fieH)Y*=uaBy{SB&vk zzd#Q4!6?k{9zTZ-!^;wyLaOmEzoPLU4sFtQI1gbhXTf{)dvKCpOY4VDN>e3DIoHtG z*tRVgD7b!}MbozQc74bJ3=c zeY0wh?A+@v)wwI)x=5cP{w#`T(ujTurSDL@*H5%_nF4)#9?P>S*cJ$zocz32w{#hf zG~XZ0>_1JXAV^wtUT*V;#uW;%$g2$chulT-}aDS1UHV{0o zD>GLZ#l*niwu(~nruEp@Xf>I`>3oBHeNeX>F||FK8)!@{}q1!T-a z{W^X4@o%eZ7i-D)6CxraR{7334_Un0wYP-ri=@P7`aP!atKI0dwKL~Gd=ODu0%U;p z6+Jc^OnlCiyB@Bv<2gY{a6T;)^!cSx-*buDx&DI9?T5mPTZcIWO( zo757fFOu$%6EHIfhehuJwQ@>**RHp#_Qe$((tk+}Vlpvcswd8QH5#+#H>GA1Xiz@L zRnZ}DN9KXz&=2@XlmNeY2-dK3;^M_kytZ1{UKAks>v)5!*SW-7l2cX&ggb|CXV-u`P@!%fWhWlm9B*_`dB8;3`(@Yr_kv4Gh}?$HK}J?V zqn4R@3jH0JNN7Mw?8Xn*et#_-Lz&^1_``+UMo^d z=kJ#re#(vbbH(9;b){q23CDMc;`j~+vlXXMD!>B%qJ+Df8;Ji(;^HLkk!c@JItE~v zM&AQ0(*FXSiVx=K2uS-b6~~#hZ7~&&PNgsK|-?{fPvgPKwP5V}7iEk^RVM6Uh%S+p)@`vY*ML2pC3_WX{&Q}U*&-~2fde_)CL zx?FJvNWo`;_sK_c_KwLTO?kwOg#SeTbe^D^7ZqGm(Uw$KlY`u(Xtpms;xe3|&vP z9S4S*gB?{74=^AL&*>JUO5C>BIYw##z?4~@aJYZIso&mTGew{>aR``A@L!GKe>#o% zx6qZ9SD~6Rm*`r^AJWM^L8qCYiY1B-+hg7HuLBPayWeIh&SKCIagJ=6FB^;!eKI=_ z_IEgd2>$uy_~P>76*33tkH3@E8zPJL;3vYHZMQhgNI~t9N^pGr;zdnmvOR`F7(chW zD0*I!Nf6vC;7$GBK(@FwU2^;Oq$hqau~Kfr`Y*2AsR_)wnL7?@tWtcSekiciUjHqE0f#{nKNzqKhb=I}g* z;xJha*5~Y+-57a|n*%_Ms4JA~D3E-f+7VtZZ7he>WI%8d=a4>}uOt?+KQ=BuBhP+N zBdbQcyYW)K1}4fed9fF-+^`RGMpMfExei+2mpna@(pBQQuOG(skQ{eT=Z@?-ErYT< ze@hNNPw++3qP_6bm^R0X7BY9NnD%95aW}0bn?;&el6f9O&6VOgTqmbE5P}GvxhG%` zEQ#SV=g(JrgL3-#5wjcw=v^DG*@w%lQl2Z2E8S1mZyv>oXbU*in#<9H74-bMJ3JU8 z1#*ZI<%%C&NaoU^&8!d@+}f!|edtN+-@t~>EDvt#rb)rJ#fO- zwo--$WRX?Ic+bZ74+TJNoFQ$-t3ld4Rx*BL@f-KhmcV$a9b44x?41|`>uyUvK?TWA1TG+m7@}ibB&YY|#&@La0@0|cui5BxKGsMXG=m-9sgS_5UPbPF~S~Gs_Nn~az3u+YKebQfYb4j9AN@v4o%C$QzLE5KF00wf z9qEs3PS<~cvR7x|Pv|aSlZnn3u(<==fRgWk%HEXQ8hpZS9t`cTpp;1uv3&YEQ`F>F zR;>4sP9Mx87n+51IRAY#tIAh=^r>OU3 z2@7GMDt200$5k64`PXRYack5Vk0#}1^3*{JMR zauy~n(R_B8G_R~oB;kfMVf+X|)?(31M>7ocRXhPgP-#dQ^VaI;TsGh225nK>*CFh1 zTpyQvg>`ZPW6G`9hlUMLg;14qACQk-Si8pj?n+^IC?2p>f&*>veotw5oObw;wrlME z3P#IdZ#|lLh_sVwBol?omL4Z>9B^=f$5>5y8Tf5!8OXjuy$t*XUrJbvYB}rphi(1e zKTYR9y?PlNr>Xh!TuyU+bhJ#*O&yj#h?z|HJuwEG+{ow<$Ptna2Y1Yg)-oNJ<~{d0 zd>3+)1^1kQQ8Cb1ku2Qc7t_T?X;eT*UFm$oK;7@g)&ue=-Dnj8+vKy(&MlOVKmGlN zS{X(bX;d4LPh9O&0W!vab3I3+S`b?W7pwaa13HXXOW z+pQ8pX)Gk9YGu5*E7?yqgPoWMvKW&%Lym3x zTr51;A6_ybT}z3?L#WA&+sn}=+*INfw`(PZqHq*9u^Rxp$DJiVDY735oBe034l~Lz z3z*KqXl;)B)Q_2g&FdsW2z(CF*vO-*awd`yg<^ zdKBV@r`bEUObP2?K-<1J-rPzP^^@n_{XVgkiLJG(o3qac(u+ZF*rKIL@(S=S~i#A@yi8=YsvD4rT-z-wL zsnSsjvh))OXV}OT`{m5Ns9@QZ>&Ujsa~2_ge*HinPxAU>+?lAq@6q#=g3AqzD4GW)X*Y}Mw-4kAA?!MB?GtoM$>OVP+_V(=#zD| ziuqUX?oM#OFelbtnfZvVeH50D->)z4+oBd8eQ1}#)px@3@)bzJs`!iN3dQ6p_ngwy zc@C2kX|Kz`Y0OL{gHUu!CfsSy+|94*FC-uAq}J^Cl$Jx>fCR8-)x2_E%_{wdu*DqI z0kzV0ol$8}q^L#-o=duc_d@=zeoWqGLEoyV?LN(fozI1|qCry*FC$}O+V@6n=?pOa zGyX?dI_7t@DZfnwTb7a+>+by&0}E_JR|Uscc7t5+vF|8&XLj5wKK&QSzX*TF5yS9b zwRhzmAnK{9sj3#;??D+mxsyfX=b#;n%WG#k7TqlUU9@BM1>2EYGEVpPR8m-rt2q%A zRIEfHz^GPo?#Jhom=*p@+s5JU`xP{(ukzCW`XR2krS7qbzY!AWNvYmsZqlPDp6u2c%x^l zp8%%Q8I_dw$YwUx9r8&7xU8#0lM&WFShA1H)6K?)_o+9EBvUHs%}yMN&n}+UvKqPp zS>Sqj`f4TpN;KxX7ge82T;Q^yZs`=4l3*nF<7K5t;*g7645Dqb%7D1k?4Wx3$L*Ic z{(D<0SC8>apTU{~;Nu~XN7<=z{uKWLAJR{lJBC=&~qGaz7 zk?iahWtK$Qn<8bU%xK6+Qc3oT5)Fz%g|<~u#_#^p=kvXtbAIQKbNzE&b@6_`#`F1j zKE{0n#2)e{#lrEpTa9N|YBpf;dH*dM)qwL6?f&mE|4m*0+OwB~<29c`PG4sAT?|6L zTKv)^UbA)e!JZQzv92D1XIX3zc9e3cj9f15K|4f-wFP*$+@z7Y$?YsBzUh#moZ6U0XvUQ>YE2wW)=oS#ngHH1jQ{Kn(Y_ z@IOcQy2Q{?dvlq*UZ@BO4{2Ad!klx{M1O!8^EGit2<2297UQI<(+)S>u@Sx-jw|yK zAP{Et%Yzj}B~0Wro5dyAWRzd3JQie7bXIN9+^%%=W)8^o#i2AvtNZ`*pTnS}A@ zIsJQ%r_9oHFwFzoAikUC?gB=4mQ3$VlY4$2Q1V(3Y_VSE66Ytn=tf>QusK|BF*Gt8 z{(;@@;qi(!uv1N3Y2ao1%%eaiFOI5fUp4bA2GP+ zp?f0oIQe6E|Y*s3Ik0>0|mA2LK!SPB^yjPZX#r`5p$ZqB-VN|^D z5&iN&SPvM+@j2POoN{XQ4*k;qn0@6 zEf0hyr0;JzXH3s8Xts&s;-yP{e=3*<^mS&;z5!X;Ou1~nD^c#GKkb=`tF$baUP$-B#bZ7Z2JmBz!eHpiaS&!d!Dc{Jwg?*wxrB_I+%)_^96%?)YSb- z>l*%p#~Zi_v|3{x7yV8PnqU^@!=Iqe>a8Fw!IUugJ{bAUW*RFIj!z8!tcc*lM0vkt zBOK=`Znk%Z^Okh#g&llUKbT1@j7KeJ1dggm3>O+YB0^lFon&9S5NvEo!KsqIjaruU z!*-Wsg#ro-;~0-ZucraV?c6Jr1~)d&0Eyx2t(Tjn87a!`G&W9dE)nIrEWMmf(^m#j z#QMh*7ZGG-eY5;iA*yJJaozKg6y-B(@7}2w9~^%$4(-tV%g^21-Q!|ePCn{kIS&P+ zG7pZhE~EL+NnS2kpi4gX+P_38s&Xj4agf^THr%ym{PN%9r&vK?;S2^w_CO&JJ z#$@T4QFWF7JE=N8*EkQ{AFEC1r}Q^YX57mxa>Niz_q_FapmDKM`-h(Hln@fiZ3tS#HUp zZ~m%r?D~x^YH-5|DUUqW{bw)l#pwuRWItzJ-#$7+2*jYf;uh3LnLL8Yzn4OBppsJ? z+kay8Mimt8A|f1KgQVa5J{m|Jwzf~ja&EWc=t8p{`iNg;KO!IYO4hi%xVVVNZytu$ ziP>Jx8~ao+(PZ=J(TPGUNRwx1a1hJ5OK%>qF&SCejKNMd;YD^eVg87jz=@h>Reutlup3^C@Cf)<+!~@|}tXaO-fZBcR^v^B?yqXQJ=Z9O9&RpNR>oV%PA`#sG0{q{)Olt4rFTIu1*ns z199Ibo4dtCfhYYM^O)h|YUPG2b zx&FBw-P?-n>}>zbsc2*Y1eVPG()J&GML<+a!BvXnFl`3io7e#eHYP|Dax$mC-jtE) z6hzu7ziayHrq~xtJ*;F+x(v_jHXM*0I%~Oo>+av_yh?p&!TeZy7Gk2lAKyK z2)7CD*fDVZp!jK~!(8M|jE`Q{X)Z|79b;kEXS=$&=z<^s=SK3+3AuQy1U(u3+bwNf zA0nJ>b1$$k?@V$)<5~qJzn1KT?>n}Q9!tQn(a}+nF-S6ezLP${dMhLY1ytxkx&I)8 zrdV!U9}@*myzOj&#wMC~Ce~ZPDkoAS->U|`^~c`rnBY|~2yGYa%iO$9IJ<`^#_2RjcdTGzD3@q~(RF0(eRf6vabVLn=*U@I(f{F%e=8W#1o)!mD^hhr$2awjp&yjOb-{2*( zls-|9ny^;c@kFR9%-R}CZ<G@b`L+4 z+z4Z>Tf1JM2 z)85{Ww)o{&k@}*lU8T7X6M|21@OL+enQ=G?WafB7%QHsdAnoSw5EwYC zm^K|47gkL%hoV#?%xS-j4=zrjT=!nSu=-n*wg{FU3`s^>@Di`lx`f*mY(GmvF zx+rBv{-{#;(Qc1@@j<~h7R@izP%AN8)j;o|p{I{OOuM@J;rxDoPB77;T{!E~brj@R z!u&X#R}${N!2>%me|iJ+DE!61@{Z5Jya<84d-n~HJ0*F88~q_sIT&R0Z+q+C%=tqJf% zwwDr-+P6>rKB^P7!ZL%hAyJ31sXC#Eyq#sIlZ+3UuR>;J!^XOSB~(4sWy^^93jhN( z8bh@ZuHgT8lP*s&G`rEB&H5=dYv;yN7k@3rm4yKu2K&i--fr5=qUZU0=9#v?o1Rrd*Hj+v+IAvTse`xq-@!=yN2(TDMQnT0f&^-H4?6BiD&WXn&fh z*xr9n7t%%f!43f5W z8j~0RT{9~pbqC+m4Pb?E*&_jfSz_Ss=INQTN5Ltsb1xr@(3WqLm~(YJt`s3Ll6}l? zW!48YN*$6VgB7$fkqj31VXr^UmB;lS@&EQ356(C0uxs_>`39*Do=t%qtgJtQQc29V zGbhb*xu|=yFb8B{VnoPPb@ZsI^677`BT6gjkGAQ@#{YEK0>_b=}rssFS)Ao7-O<5o&?Kob%ju)0oS0q z`}p`|1fI#l^Z2{86#jec#3X%Ou|&zgiw3s_g?aDPvY@%uQakxTit(->?hdq7VG+Dv z^O?{fDH$1<>W-!MvK%;=tgUl$ZkRQS_rVnKpx(`l?XOr9# z;xcZ?#jR@C$`82MduWyG&j;dAM-$qD=xh(H;EVT)g0 z9RrZ(--n9=4UTkRv;CptX4tgo9kPjfW&lixMDUv7Hdbm~8{!u28#Izn0%#qmqzR@` z6PUOBAN%kc#ciqfj~1DUu(;FNbm$Z#WzMoe;9J(E=NAxoF`7*sH#r8BhM@?yE8&Wi zi!JpB8FzA)d>i(&SIxtA315hP-4-0i% zu`mCP91zFoDJeBb=ah>BYc7dGu^Q7%{wXmQYTaDj4RroF<&*PnKv!if0Xj7jt^vNCNsB#6tLZ3!xGayEtTEV)AY5 z!Ch<{Vgu|>riu{k02SyjbTg>yTGXFk7~2MaV01KP58-*dWp!iS5Teshml)seL5*%n z832fxL7bwvR2!YcvfjPLb#--M+_QR(rOuSyYeuDpHu}cP>)3-$h}nFG3r0Ng@$vjM zpi75sZeKvyBdi{+_t~t-g6s%o8;%>*J5VwQgb&D3&CruaVWuT&(cnmqiqHR}P1tdf~^z`CAQ#_9DNK4S!{B)l~^`F`M zeku=Uc|JM6*H`d+S?7M^B4*ai>Q_T!4j9L2QP^}4_N0<~kWCI^WL!&%lmTUA8)42F z=$l~JfexX2s7~nK>_6wTO%sgr{^s8g)@##~n$<9ORE^al?kfTJg#i{cDhwp-8yK9G z#R+XAC;-=cTcolw&$AB*6y7=f#>7UnQ%rQFD7EU*F+l5>OkA^E#8~7&Hj%ua;smN< zj{#7-IB*kKtsz__dW~Dgs!#TPr-syB$G6Tm&kC=b4ZeC50TnHOuDAonc7+u7Syai2 zi6z^T4bMu$9}SoS>nL!=Ul;8Z<`bEEoBHsl{bxVbk{=H9XGDGsc9(rs8&ZX|1bRNF zGB9|2gu3Mi4n9@YMz5C1B9@`g6(sELaV~U|I9Nf*&v0qYF1;4bXNSb!V>6U%JnriD zVCd`?T0dL2!MIp#&#`i>{KvSEa5Lyr?7;580y6#tXUf_c(>DAjo0NU`d<_Tu*1>fw zE<61mCm*)_X~dO53`@2C);S7blB++y4|9y;7(^L>)LN*4kTrV-jU<2uk%gd+Tfo1r z2{sV`#}&^OobLX!(6*YG7VoIr?bEEwp>>)e0b3cBoW`jM?Hj+x)t{gLbsF#)42Zx% zlwW5gXth&CeR@06QeVg{uhd@_2)ppNdgaW@yY&j&8@BC@bKk$I`aDpk>QK!)g_0=o zfs3v+0Ma1GzrivPI?qR>L7DOc2vR5t1ftHus-=y@t%IO4JnQ2PfN61iyADfAdiqhc zWSP$Wco9dvX;b7TLmf>^Q?7&yP+MmItJfZY5o-xt#%@DdrY$)N>W|$DOoCMaLUpa< z7)j%hkC*lsXfzKk%({&B7@k*AhrtH%f_iz1hPdC(tr;w396e&ZH*yH>?4b|9Z#&-c zVg0uE%vxi_pIgk0RPnm09GtAa64{EMU#_TMWiUFe8n6i5)bKOFz;Y=`6}A$T_k90R zbdm{z_W*wZ>QZ+R&zXTD$`)GPG2^WAS&l%87cper$DqQ`LtI zcoN^MuPvYLUS_U$E0-L5&|2U?t2)7Dq68*J`LmzXKm+W&*i4N;MMj^_`>_GHEU zBKt;tA@)R48Eq&=GWJ6{@`cWT?zVqd|V}#qo!Wh=;RsJmO8xsG;aCODnh?V zP>qIhLh99zLRnruvH{_SQ@X#m6H*2+VdeV1z5Mi}s0vjPkwkk{h+)%Jd_yM-C1_EM zGK&<;87?pWFCPfWX62*-O?$tVH=Ac=Cq7K>yXKEzgJS4j-GEJ#VEF#y;qWzl1wu^n zs=1tyP#pgp!1`Or$t$LF>N}%du9L8rG4zOG$SxtKKcGJ*)0N6`9<}5tjGxl;o@U<_ zZKSfgX({`2^0?-f^*?tXX~~|yJro=MUOl`X4cgI2>A|KSjM@(ZtjT{Ok&a=|{>NKzVyCA+Q$OptdycZWm))+YanXier?#3z9$ znJd=>`GXy0;X=cAXI5{HagFQ7Qd`$sP)HFH*PqNnxChsWBoTe)|W?~)M~?kqi< zl*8Gw=b<=ZgE$X{(i~yxg(qtO1#Y5OXq(y!5t^?K%ZM>(**FjEsGJ-}(m37p>x5uG zc!)I{&l=GPYv$&bzxH&3Xh7GaOcz9?KzSgZbyxKNh2pJ&0t$;vYATR7@v8pC*)7)| z34ZX!Uxsrm1(@xcrw#z4XbZKPuqc$@vo!a7Ky4Meg5E)=ng{G82Ptn%9EIrbg_2=J z(u~~ve3&+vjIw;sr<*-kWq&U^6EX}PkaiK~RE_zy1Uf;W)+2r`A{0?3FHdv%JJY=V z&P#98(LMpo`HaX{F@F=<@p8N?6&|$Y7xt{>QKDPIYPZ$#Nl<_oUwg$*RYEhMczrPv!R`+ z1hJ{srXP)Ia{Wm*ln-d{?40yHr{Pzw+hdbHc22hC|B88+6DF`N?Uly)PI2gY{F{KFq{#rCwOd1~;`*}gIeYa^R0er4ou8c@y{G34Oc{GHFIp&(rN)+~A} zOI#l0%4dcZEcR30I)8o$1o7eJ62WjguAn;A_tLG2Ww{&i0Cs*ow_44kX zL~SeCIT~+e6`wU6(HR=s`P{6gs1#*8 z+Sm;L4g>OlpE;bTp`qdLgh|_z?Dkcpg-lmm2hy)xzWii*+_Y_O6m2V8?+KM=TykO2 z&4eMC?F^jLDwxw1d`J6%*JXUKiD3|$GJhF9ZQa`7#4TwYoln19Shq4j+f*VOY4@sp zKTmy9=79U|t1l8fwvjy|H)l-d(|NzJuWe)PebfJ@OL~;%r%0>e^oI|WAN`WUvX1WA z*k|8Udev3ONh_5{Wmi0t^?*EXP5E$8@3a?%;1upP3-Su@Dx&JIq`l@A32+<7fA%1n1ITa_>#AHk|xj#2ezU0q!rnZg=I%otfFR#t5? zK{y4PjyH-Yx1b4f(r~APyLJQMgQi_b!1`f(;DolyvwEY@|)O67c24MN@cAe!u@28-k z-5l-G^iz`y(2|R>EI~*z6?(Rp?%lZ)75H8+yY@jPoP(UtpHm2F6VYKttxKXOG6g-Q zV06Ja<$=0S={7LRxl6!|`7Wu!$a;s60ObY&nxi=`iT^}AF-lSwbCS3 zkhRPqTmuU~aSd>VvNJQ**Vm7o#t@hIu@-VxA)SpMQzCw>j?ZQ@*38qVRT>t3;1Kem zWsruAH6Z4Fyt9@Hf(b;jX+C9Je~$QKjvYIiARH$Ml|f8>hBH6@(#b9SwsAAP_K(>z z526Et6z(>}BLyLuAqUu?ZA0smtWk2DiG#O2_rG7eFGP~9mBUa3)(M8{;ijMTiL1#P zwP*dMLnN~v*4Eo3EgY{MD8p=l(EXP1Ic0P-nxLGQ1i-aKvrX{j5&2Xgxv9f?jes{y zIR4D1%}dgHg20I9RTo|J+6OV=X0@CP7vi+3m@O8XwQ<-f?#O8&W4#*143rqllm84vg_>-~e77e2I^T@4N-IdLnp^$yI75eHE^(ptRE=?rx!0Xt&W}U&& zb*&OBh5N%61lB3E9nm3SE4zA?5at8+UBhV&3UJA|Dnpj@Qzt<<<@<0Nf}L#P8m;Kb zgx^OmOG6g<>;ok1d4*?yX+!FxA&jVpfP5AA0!Y%>h1QI}DHo!)5GH!dg$LNN56 z8I#fohy-{XhTcbO{xK)_8@b$~{)^qQ$jYq9Lq%SWnMa&CzZf#|dLWLhWm+l^rQa8h zUva&tz9t~~{beZ355$=6`OcE$QZOPK-@0|nmsb6U>!bx{9M<=PMI~t=CvB{h$4b`& zryN)&Vc16#5~IdX!V!1AdrG#<@Gv=MgD*g=m;K#uB#Z)^gTgtMqn8E?Cky81dMItkUcb}9OO zMngAm*D*B=7W2lRZd)<}QUSd>zK+s9^&*$zRrqil8yE~%0>>g1n%=E%p|jAs$v{wo zIUgeFmbAM-=y1Z{z; zwQBT&opPnZVE4o?cG7!aOQ9{81bEJ1`)@O2=ldF#2GH(0U`+lRT9lfWl!`jHNv1PI zr|=Vjfq~}=f9CMsWcdmU>W^68P$MuhHD!C5#$Q}q%-d2iExeN?*4Xmefz8gR5C91i zo7>P`7!30}{b^}w2^1)2!vi;Xy`_GU&xP9CbG=ro)60tS&-dNRezDUc5+$J7;woDA zK(}3%LzC&O$OOiu#r=1qRe}y?nf?o~GXo?^gtnpTQ#0ezfA_TZ$Y$-VBTG}KCP>w5 z@4z*YDWxV2hCg`h(^>Kay6t+&R9&$rDEJH!sucE%eLT0G$RI5)PP3tjZ8bcrCmX;J zHjt!5@oaDUmCQ_+n>pBJ+DnA`3DACorw1X4L_Kcd?=cr}=>up&0j&e1-7{DEyJE@c zdtzvM#657f(bS#LoaJ9`C2g<*hK@DpTgrc~TSJzG`7--wzdJrJu9_Bz5hy5Qv%xN4 zf#akNHNT@T9E8H6F{DI(msk5b4-G}s^50THs1F|2IKWw(K;tMO)9 zOX%TauGP~O`-FdoLU~R@=9_oMyp&g-EqQymxd}drJ(F&@d`79mjp#nK`oY*$p({k` z^mh8Y1<6s+%u$%d(a+X9%>2Ksm$TZ*Nz|!f7&8Zn2us=@J=2$4*ca4?UJ@@;!a}0| zo5GO0g6bKf!Y*$0_B@~8V7z&fXQ(iVUCDe0r@p!B^V=9`i5QCy^I3YT2{(0@y6|7p z;i#wDbsHL#01P{+%!*HhXwipul%Dv=asl#XN}$tSxXYF~HE-plMo>jeOo>+Z8TL6-p6fe|W$` zU!YE{T+@!}G7~U9n8-ArQH~Tz-QPlf?FeI(cry)8qk2qz9<`|OA`4H#V-;AaD(hHM z4AN@v8acwP|94t_{S#c8D7c?Zc2ZP6ss3nBS;U@o$7zam>s`b1!Z^2<#$&dM9l8a* ztRta8D-PA_1$860$xr|Jv{Oet{OrEaKOj}wFQdyJaHV<|4&&h+ikB$9kq%HbF;9tTUn6cab9he5gs1JSc*1pVYpbACTudPJ0h4tujD|+qQ#Q#fL!c*Q!%716T)KV0Wf0p#&9p;-|ChpGo7Q4Kc zDx``kk7+05-&VmdF5+!aySeSN%6c7=t*f?K%G;v?&IQDN;P2%JCoV2b z${(A2C4AoSUf{=etzWH|kUEP##q(Lxkgr&asSDpJ z-=XtUfJ3)Zz#01XLWX{jz4=s4=(2KsWoq9Am}dHIOu2U}U*8?!fI(`(rYAZI8H2GZ zK^MN#Zt2(3po{Z?OGf2yx~FqETq-hW*ZeCH;6Hg!p;dL}Z0D=0gu8$RWaj6mBx&2Dd#7sArdaT7B|7&b(~GUQb%1qAlG{>?{Yaw)&rG0=D|IAoKCM{v2I5RHe`e%2$aWH9p4)>Ew z_l)QpG-#rNI;)xjKT>lY|J+dR z`l852!u>y(uLlSmfX;I$w8?m#rDSM)A4B<#?;Vhyy3fxhHqF#LR(fe}JSush54)P6 zJ7qrriSmDLFPG-?j@EBT9W~>54UrK`te%xVv$pKXq~=9#IDxF*fD6uuxi0Z>aT)Q) z0ep{Tt<^eUcQ4SL=^a+0g(=E{YqUY9u+oo6G~tjaJ{H?$GTj`OlqY}4kcW9*=SMH7 z7n`MPkpue%ef z-gx|ymjAtyCK^z{owq<_*I=OWi&r{>VN%@JI2C4)qKedoe>&G@9I?q;o=lN8Sb~g) z-T_Jz!GPE|?h;J{7ED$O@`86z@FdJ%1U~p}P3Q$hx67_t;u9^JA~rvYafr<)CppBG zy=%teK91b}bN|JQ7dz*Ra?E-#Ylhz|h)EP$9OY5Qnz8|m=B9dB4HE<%(j}u4M4=^1O*M0qOuaq9s%-bT`^mn}aT#Jalv*?0ud^ z-;kce5Z&uHeg=|9S3!q{euyFz6YnfzWD7f^A~1#H2zZw6M#oD4%*ih$-q@tKAWAJb1q1H_Wk>C z4O!kWYX4?IaT{Fa^DByh#>RtiqP= zE*9FqV;Z&8Xv*D^xURqi=&<%){TmQ4;b*I57gEs7;f!XK{Y{s68?~R_Cj`K&rC;ty z`3_jrkHFCpvt_1!&^T|6AB*X!5EVAd3=7;=mwndj#k2YMcK*UzJ3k=NHP7Ci7xNHc z0hV1Y591CeDR47vnPz3yWEP#mDzmw&nQubBvu}C^gPs6jEDXJvLT3CJN)Pt%xC+V4e3y7VLo{wR{9hfp;V>6Z7Zm4S zd-l3V>bL`CDHz>|cDE`h$1z0OgLA%zgXZg^T!i@UhOilTKEN=kh zMvb#}d1b7Dmp{XcecRvL>(b?xOr`BPbQ0a3X)qNConvv~n2iyg)2*^An0ha?MX%HT ztF7!zlc}!ooW{3~ndcHa;u2M_s*xveChO%@&G)e!aU5X#`zm}ue|Y>m>)7E~=o`1~ z(wQZFXEwZ9CH^(SH~So8Fhc^-~=`P< zYZdHnJ*Y)Xy~nsLK#0d{;aIEP*H=|Mbz3J5;y&3hS!Q0eEV&co#m*m0lT3A@0Z|?* z`NEzCwW-8glJ&fmJeY(j7~p;Xfh1~>!f?SBSq}N-f9Ju+2;-GYm>9F(KYomoifV$V zY~ep*$Fg!&k*WhjKuMbL0N)@iDNl8}R)sEl7du3j-34`HK4V!!3Io13&}Rz`3me>11}q}< zX?6+=^Ka@RK}-`_$|=oB>@}w_tpHVcat;k?j=wp+M|B)!`ECNYBJV|i46n2QXO>*T z|9)AT+P`zW|+%i`BTWR>igGxTr^6o!4EddYSN<$M9ru7<@YU8eXmc}z?3Tl+^}`9ETSFJ<{=f4)cRyACPfTn|b0~wM8{>6JD(|F^oQc>}*msUywkM3NL+PNIC*r}{F*e5C zLKhNXheln$6fHa)p2VMOl>ZkB*C!_?%nL=Q@cQ!=yyal8S99*6ND-Bo1o}MGCna)j z^l1xT&7qVijCZ&nY*W?0w(pdQnD8lWO0_>T0!9F;=I4KjJY?+ZY_e}(j0M#dsyS-X z72pbWbakoR-wJJ%^~D96#mE5x42suZU^|pwi^73u_<{$Kd*efj(E-9X4%Oi1e9E85 z^*Z8Jwuuua9uieT?#2Lo<+egTA@lGj_QTH+NAVLimk{QW+Sc@+*t(G>csb^{AQ=kz zIvmiR$oSv%aigb=XxsC|zcfeT;4Dnmqw*3Ph9OrVE2oskDzB;00O&5|d7eEpib$;PY?W7OFnFVU7w%Dl+_0rGhRM(yJim77e-qONKN1*RPi zY1+5(QX0>!tC>6`=}1LMKuyj0bA4nFbA?!X#Mqj>u_v?SNDwB*v*Y|h|@87CFfPJgzYI+_}n%ydfhE=`YYnVq5CcN#m1E3(|zs^;Tkz8?Yzxk~IcS&ECj z{u34YhZ?T`&hZMaP7}N|dkUB>w-tt9v(K`*2|3zR=*~*MuG;L7Y?vVQj2h8GMqXaP zwh@40aAoI)%HPpjDvZ@02M&HR|P)IiM^hvvbo*a-%l4Nb}RLlKWHL< zrU9^;?#mT;y}o6#{Msnf%fIupvjePEs4%N;-n@D1*41MsZzF&vyYHxF#v#S^bB6lW zZig4c969o*T+ht7Nu+1_4#fs@*S&-xJJ=YYd`i(4Vpj1$1PBx-e!0#$H6GgCq9 zrook}K=2jO#y;maw;1Gb;}ioL{oY59(yM5@&d$$ce_nq0a22_SS@bBii;=#?By(mt zy~YeQCJ~ir=PE-a7}1^;aGi2yo-xX!jO*?;sB9||5o?Pp*^%pCIrK1))YQw$>gD>{ zkM+#UXU&augbSMWH1z*c>^N^&1U+gEC5B=D2WBw<{(DFGG}}e?3KtgUc=goR*H@8u zkk^p5+C#A-Cb6Q3_xcA? z=>)?Ummni^?v{4qS`*IANhY0F*I$Rv_w1ZhZ)(o zvWbV}X1HPBxZk>Q6^OpsC+)6GE32!L5)vOgA2V9UZ`{!<41wUmyYKLA8x4WflILR1 zGhVrO92BBc#eNmIFsK_-(Wf}td~~f!rP)|?6OrAnVud*d6wf+Z{A;k_av3boPkF_b zy-B>Egk!C-pr9alB3QWv(I1ux{0ei2OBN#g1;5Zfqh)tqZP~&zaAdbkJ{o25oCjJk zOJZRDea_*2`XBUYoH(3>W|)U~UoLvJ-vv8Hc<0XdX)}|Cwyftjb?7LDJ6Vr|atoCB zq`W};+zVDVwqEl48^J-?UL}nI*JmS}(bmMo!dx4@$WYvdXBr$=n78lKOfr0m<>u%( zNSP)u*Q`Sm2YJxqoZD=X!KtLwNg?Ro34R>d13${$vvgrQ9bZxgj_fDogxRI+o8K^Y zJio&dfPlahUf~=PqNo-h+@a#dCHDn+#KD6HpKUeXd86egd!leBT#LBl*_&87cAKiN zWy1ilS)fD}T@xX>H7)lB|K}y*xKQSe2YJNDr;v1*63}|>xLP><)oyIw3XcW~V;N zJFq!LpXI!&XYvkB0ehbACr|3@>M(~>$xshZMZaV`5(k)`hsg`NWU7ZTZE=3FlpqCD z#`Ot_g&xFd^HodbEqASHdeT;n9U{*mpu3#Zys@txCVIUuRrr!pCmVi$N<3hxRMoTj zmCwy)s5LKWM|UiKAIqm_Vyf~iW4y$fvAq{Meg;x^nK8QG@-8i#H$u~`~>SWG|<%;f)ip5`Y+}+*%vpAhQR07wx1nPa)EF!(9g3O8Efy(-3 z4oW5A6IaGL6k97iJScaX8;4c#++UG`wn#~h# z`A4`iNKUrg<614|>Co8+Ibvp|bBh@E_<%}`P~*9AB%1Yy7|UXOKPmAB1c18RY>JAC z1ML6+9*LD^;f@de0idm%ynK(6xwY~h5#c`0fN0JP7p<&Z&xH*E(ByEsG211snT&odt>{l2WOgYjW@c!@@&@_D={@|&n zSFR974+5vkh6Km|I;mj7lhCX?xj(*3K%__4I98%*1tY0Tdrr_xlJwLDTdKNc(|YS! z(Vy`-den62WLouQQu%CCb`TEzvu-+`USwpVX>k2z>~G1-eCxC3eT}MS-~t5RXwZ)9 zz>FqCcejGpli2V$Y95Z~nmdl4opsvLK>85bB-bi))Rygnuh(}{x*lNWmT}qCqVCd8 z32qGtV&tsyJ~@OXt(*E_-1}70RS{u{t(jK7`9){fsjqL{= z;u)EIE`8Rm#zro_hU4FCy{!ua?d?aAaNJS*Na$Tqy8qevmL@M{8|%Sk?mz)bjdJQ( zo7APf02?0|M*j^=2Osh?Q4E68ntL?;fhP_5Lcu|h$m+g6{QY)2h^wn-8HRubFZ-co zWcBd!vcT5X%~pqQ^b4MEQVuD*JYl4UB@AVb&!094!Yu6&2ssXb`)nmgdgbKjuF{Z%%rJg_&7<=Mmn+kU1$z7^G%WzQFft z7>htl&dIKt#J$B^qom_^H*S29DLRd${k~PpDvf4?Miv0oJ)b{9c?-uX!_i-E{#g}g z8erM7ZHzUXKg`8#$iQZN*DFfEo(FzLWDFECvp$V3dv%67_QFWF(!DY&@#GkgiTRY2 z*iJI3GMwC|I7;@yszNgC3tFs9enLm8V=xZZ(&$mT_ebY*%BO*%HjG?`54dWmCnrhM z_b4lY={2hh($Arf0d$(H+UH7W0&UUsMNR(12r8sSkKFcC=u_qTA3VuOMMcoDd5xjJ zxeOozF~s}6B!sFgvWH`c7rTc#{GIMjA ze3wGc;jn=HwZ++4UQ-6@{DK0yiI@Vx3pcJ`Z%;<1WvF9zJxAp3ojZHsBWh&S3%tUd zCuFlR5_ERv8w@h2Y>*?VKY;>iX?XE-6k`!jN38lTMa7PInC(2FrcXYWT=|@r3(ZHw zkU={hu7|ulQixi!(onqfk|c~y9^{wMIV4~6kQqfh@3Hu{tt0rv3D2wd`R&v(EwYy7 z*&Eh=Q+(#zH(Jj|vy2-nX zBbtDwbUvP_;pIdYG5PqWUQ{@9p@_&7M&-yqBk3;P8yFY>_h!=0Rh(l-aK7>uG=!bj z_oZJpW0nHQ_V>bqc8Ttfj_>ac2Fh}Lgze4tb)&$(yy#p8Pi?{EBngJ;L<2r+>`wF~ zSl&G!~&gI*v=iyPLitPBPeA z#{3|#Em@4y<^q(LmW0S_T#WV#m*ku?HxOH8R=SO*20BS+UV1HVoblHfcaWW>J96X; zJU+==(77KmiYI?)1;!#qgo{R$n!)+GToG_KuadK;gm8(Vt2%bXvVxHVvD#kAQl+~1 z#70eOYHD&iJNq7(hwl^f*`!6A`@_AsoSw}_B42l22`3%W9u*qY?-m+7ljd)s289%x zAlq#G=Dtf1(619d`G-NCRlT2`FRygxiCAg+{+LR)ZM@ks z^#)vCNyd1WNxl9V(af>&phn*f`C@ha-Gem8))#PzmSobn{t9YplML>W9W=DGn2@4z ztUZr4u}%LP0jC)hFm89Wmjvf@5k5+$euT@_R!h%01dHlp)?3SNs6OSD5TUi|1k14YaJP{BhM;I4TkynG2^m zxlA}8glZo@F&4!DU=wDkXH`ey2_(qkJ7dBalkm}57JhrTxR~_bhr@e5Tu!(VP(-{Y z;o5v;r>+v%dATRX#*@F022J+T zksUIAuZ4p}p&WhWVGxjX@$eB^;nXy26gCN+CI4)>l9HMfHK&9UY2Ivr-ISkwedTb> zUyF>C)ZX6y`t|F>5uX8w8-Y{~+zaZdcu9L)V(_9dT4udQmK0mneg(O(@QZ<212INbIPi0yiAma>JBqCZW9HlI=vG`uxK?Z6 zb`z6M2aT6<46cz7a|>N%`tW`!6y8q#=qwsg4SvJCw27(H{HERAbQbKS^I!j>#9aUL z>XE?&YCBa`Rbom%KYf_=Keznk9!4_5%|D0?SxD&P^z`iupXvDDjEy~X{@xnIxkE(m z0CP~#0wT@~=L5SfX4d2s5~bF%`l;LIj2hU<*+p;lZE}7X@`cUrb@eP2yI$-cLoVv% zq);o8tv~>*z_J58f_j zcr@>6{;vIDySR#tuSY=y7WL;^-2S;!9ec0V5J#ESX|PVa!^UO7WS~D=jhw6gz-nT8 zdVD~|^eRbuO=S2<^hjU6e2Ib}QR?_zrHZZVIed-oASI_|ao1r}8MnYRy4 zoZU9~i27DeXWVHP=4OY}3;ny0VaK>Yuwd|uei(@d;fAHYwj}T%X2B{5s5h{;uGJpFx#m7S%7p9ulN-O?*llV?cSR# zqqv$-T+7VhxzxGIMl~FCp1u!K@z~upx~&~tUbjNq%WmAb5!xqwa|V{0x>a6Y4KAGQ zVHSM=lmq&44KNx)_BaQVyW5Iy6EW(t!HJ|6kvGVL;4x#0`^r+ zX=!Yw`H9m@6I-B{6CF)@e9LqJAvge=!T6)llxQ#1F5qNRn`limQ%};ikwqiF9wS*C zw%UXrx6!_RBb*_g0J~z7`if4E5&U5|afKeas5yyJHEy@bq?r|AF?Ptx3bhcPU@!#T z@#1{bc4ua1zd}c4cbfD>0ppuTi3 zFr_QTa~!Pc;!4jtv-;&Q6g0F0wJ+cA`#$BrMvX56{2Jpt?SwPHsVy!e`*l82A#4>X z`O!ZZYeAqrH7>3LmFtUgQ?B$V+!SWqXbV}}*=fsS1N`kg^wC+;S!VsU5RHl+e(n&k zyYR>{v$5&<{@$OH!My{f>0{+rPWv1=Les$|?~yt=uVo99`2d{m!II%U6BR|*ulK^c z63^F`{nC^_=O+BlyQWn%#GSSx`+?)f3@Y~9ik33rOS1^S^;vD#1YrO180jUtoRA^_ z`0^?4hc>m=1y36*oS!e+1#LDfOUr7-ED=#r!oTwoWydpkA2%+6Yq+@NOG~dW)SC?5 zETz*cp=jxeco-OTV-h{gS*vj`tEox+xPtxqU@Euw}z37WN#7;LMm@7QbsCD_TIB7WoBe#wM1o) zq)?I~Gn9&=Q1Lr%_4%&fzt5}3`ySVQUFUh6$1wT|8L01Pqqvd#AdjM$2co$GDrWgF zMea+vC264UY}&L5%7F-(`w99k zP6g9WKzK6)ccM$PH-y}Vxv+J|2zwF?#=pRO0tGRsdOrxuY&^1$STt7F)$X&#?!L8yg zt*GdYf8|Ph%HF{NERBkr+$I}5fl&kGp{I}Eu#parBSS&cQUb`~6 z$Xcrby-@<&99c_7i@J_ZXkFbN&7YXi%&5{8#EDCZ<~(a?Sbs^LjNGaoS1P4GasNZq)5qMP(2fXtN0aK&y~A@3rGR3Tt)#NCVy|lE_Jopn zx3QHZaCYi&6q|P9{HEvJsee=kX7GuCi7tC8#xnKenZ8A*fG@TJtLIeV{!ZZL>Qa%U zQ3dNUdBVit*|TSf3+1~NGg>+@INs^M@*8V5|K?4oqB91cjl9&gl(9K-1X(>1=1K1| zO6RWPq=5rVIqo2L5}OFt>eN@5hc8x!aC4-vGV}I!bVQAh!6z1cX8V)1EpOjiPb{9J zD`5155Zr6&_ZxO@j)M~U7-N`qLS#wk21*6ov4jtf$@M6<(0NK=rC{o@;z|?8;?S&Z z{$+ez`%4lO3EZl_X{7?vU~FU7ghv?1h}hQ0FlI|~vco1`{!rjm!FUG1+(jtoA8PTjAZg3qzH^-Y2BuWsi@j6u{i2G!cJ=D0fgG%Pc+b3|c8c}YhsPO^ChqULn7 zFO!q!=cml>B77LtJ)i`M_ZRr()8Ry9k zMMWMKC}vw)UPg5sQxp*Q+MT&QJI(dl2llk*s=s3P&~gW&q3VD87U~V2Qo0Sc&*w>!!byeY1!hCKx`xrQ>~ zG#r}d$9~SuL7qf@z!v>4UZQdKBh#X^ws*FH$w|rY_6%;@x{a7no-sOOL4R+t$vfqH z?IRQS=7Zy4=3D zUY2%t6m=y?FW^RC&TWUkrF>B01IQI^$sISNA}LY-J_HW2_ei0hJqv6mSXf@Zy}fUw zo2kf9R;_SsWNd=3KQlUC@QBQ(4yb9Y4j#n*BM(xr>gb=(_!fA$xf>c9j>|=oZm9U| zul)&wX4rs^GW`+EO>@6;>Gv;J#fLh#;;sBmdmCHNkX(0O%%NWklz|NQofStns!bwkDSNX{`YJlVG`eU5{S4(BCS zG%gu^GMQkVm>Cg%VxCJ|els>0bGcml+|qE5k~XT=FK68?>~I#wDs4)Tai&}2iW$Vara1h ze9;e`5j5z}GSxB%vuS-+-PV;Ha#4Z$HBdsp1xHVv>y$P zzy}YM{D6no&!9e~-?dSXUmlsUvN(0EcJ!S<>5>A)9S=|GC!^sgON&L7=zC11RZ6HF z@cyNDobbjP2q)c8K5JNO@ri2ho}5F38_n3uL4#Xi&0-34oLlBSs`jmXs#|q=lYQuS zhHyA<98c-9G?!g*cORbnN}`uszxn|MAUX|Pee;*(*`bSHvv=4U-67*afhA;pi?)9W zr`0SR(P!uaF(<=-)a3g>m)F-Jp2u^}b|jLE#qYt`hQOrH*jW)6P+nfnz{PMnVj8E4 zi^b{&tTLUGDV{^?^G<1`5@T}#BaFtZk%7S8Jkwv1tC9IJSDp=kLT-U^QisFtr$1Kp zxQw64MA{}+n9XP$t2$mEgqdR{0ZaKix`-`Z8A`x`Zfu~W3HUt{Gx}B?=<{auQv4l?JcT}RV%*Q% zTK}NY9}QkT_uef%;v;Rj@`g%oWIcDYO41N0jIIng>9!p^oLIi&bB2FTPR+93$*u74 z?vk>3GIjjLVm3qTV)3h3aNz-DrgqZDB`q z5nW(E)H)adFBASrx7N44M`?+zwet(ZeP~V}$t;V79G;QsW;JkoCuE7-ZslFLhcn=% zJMMVoZvXCu*QktqPXd!@E+-S%$JI}C;w=c9Dvs<(+t<(HOzhV3E7mv<4L@WX$3-nr%z{)7H; zowEz^eTTKjjxFhsFH@>C9>0IM`fmWEuu}C;}T`*GCM-YcVYMm znMXVJpz9eKIDu|6?)SVEyl&{gkzSA{zOJ_vlgAWHUo_53fS+I8!a7x#T93EX%n`oTH5_v=<-<@P^D66-G}zAu zY>N2!k*~DkL{Del{Jf*?#?>*k)eTXWzBw@xS5}7a?A?1ciryOpC}@m<4rE-$eioTL z3PjV{#*5BR8lIQD2Yy?1fPVE-O7sB>{~_aH@OkEra3tT0FW1SwmU(;Uq~1wEG6gxg-YHXKUnX!4 zDrp^#0Y@-tMLh=LC3%$rJ=GB#o9W^{WQHUr2A0&`x&`a+y^80>wI{><`x+ayuGGIg z5sjtQBi?+4TUz=_W2@1`{3bUww>-KY#qr;F^xp=d%=+@q2OlPopuATg42OLQIu!Vf z<<%>-p2IJv?#C_Fx1yoVpLEa{N?J;M5NBYPn}+>3*HW70J7`>Yey;kZGCxrHa|TTt zDV~F!UEiAOmd3B011!u#KTu;60*u&G<1dLR?#~X`r>%?BrVMzG4-@0gmN1OBP{P)h z>fRSN{F(~S0wll$_M>Lal(B1pK}M5XJwNev^oYksMh710bG{II@7Pz+3_d7kJZ2-- zPA8he`djKU-2)>@O;LoRaeC*OKZ3D3v2hnC{%CDfmsy>wU)6SME*rSVR`jzrcC#y3 z%3u1!iX{ARXJqNh*lt2CZ+sUL$1wZ!2NvJq4>p$>Ly8KF77Hh_Fq^nT=G_nSfr6h< zX;_=)Mu8V#rvxSC%%bT*v$e%YF5r7;R_=##+s3x1pqS(`ZZEzB%%i4-l`+q(Au&9% zCyIv^XL()y{HBxEC$*0BmJ}7)8ZvMNQ_>1HN)FM{>@3w9U_)Vm+MP_Jg-JFlGUYp9 zEn@2`Cb{s$TYC8h_jT*++HRA6HEK+TY{=rM%$BW(*F6;5UY|J|+4SC-;=QeY z*Zmm4^}T8k?+${9+zrj#xtX-XeDGa^qwc2o$Ozk>8Z2=-4q0s>ZZ@?=yZ@zr{y$Im~eEEpOX;7lT*q@_R1PR8iv~Ru2w!IO{{C>5ywG7f! zZ7BS+5fev2GGvzUl_XK|e?gsTD*oYa9($hZxZ?-3uhS}wJ6Y zd9%EkEG)xHO%8C1aQifwaq{rViOR%Kt1R?N2_6tN+$Q`WR6qG-wf6J`k5@~RfA-Um z8iC?~IwIkDlq}Sg9OyyDY1unuOUb3BryvwdH4 zgpH#&N2QW4BdJ;YAuSbEp^e2VrXRG&9=07{+sG9SuMcKSri{y0SQJdNLdc&}HFr^z zk)1u_gXs2<`_fYMDBF{3bncfD1fLJbTl4C6%bFJQ&ZS`%FQjY)C)G&I6_gb3LJ1HW z3-lBygiuxXPZ|L&;D9-~E7YB$Lz+VN6EmtB!^304-=+eThLH|7*CT&3D4>Kx^omCo z=Z1Zs67Ev0Avk-K3qe_LxD~<5T*tkCVF2fO4C&i~3~k6xL&a|qxz)KodeblNDet|l zF2{B~_Wc27=NkA1``CLEO@4;}Uz;THdCO55&0(O^=%}gDM!w66R>BTjb#~Z6`^2~e zqahakZL-HIV_&jQM`JA2DPhnk@M34Gz|b}Yg)Lol2JCb?9d{%}$*zXFEGCrKp$yhDC@oh8D&&&c8WFJZbkI z7tHmhu9KtwT!lf>_I)el2~YjjgEfeG#Cndmo11}U?QrIi!T#g!V%qreqf0HpbWPv% zLeahtrymBSIebia6J1eyZhY)KL1;qhG?D_Sd`GAke)r zd_|(gy;phd=!TU)MRQDKq~&A3y2COD_U}iPeduA?N}`4FdjGC?zqQR#C*Bfk=A~W3 zI;N*u8T|7RQT#DI=(z!`?W5sI+UqT{)7vF6AvId;wcwkO!o*YhlD?GVOmQ>lrxGL& ztK_83T9TZ5sa}&;R#nXOpK>3t`pLWYoZLHxhmyHt)nYLtMG5#0}P#d_CkP#l{J!8PFR?HKXLImudlw2 z=9zUe_(zoT~FHV3py)gs;7tIcfF}tE*X- z%NQjH3S1kZW|P-6Hz~7g(AO+QpxgLY4QDU-zZCr4+QIzhj^g0rvOat`f_E5LQyw?k z-(9`xg$Iq}c-J0x^Tmme1r{gjEXo+eXay$n`~^o?ol0iOfym$NTIcMD2}p{G@~#c( zyKBWdc}jA0*^dVQwh^j{votr?HQs(O_1$V==>uBWn{5)3T$y~ z`N-Iu_w#3>DKP|n*VSe6Da+9Y<}m+uR8dh;Z5a?%#LSJUlxnVHS<_o|hUxuX(znj4 zdocH+vY~@&K_lW2Lw<1Nta}Wc?S%esOVVkvT%rTbBB1t+p@=OF2Tn07?-8e?;;Gbyf1Go5lN>l zVfB3f9*!0tAF^!N`*(K>ITqR)6CV$2jcuy)U|yI;xNXV|E_GRVpR@~Q-AG%bb`kGn zYNK+!c=xqk$06E25jH9j$yq;|dgY4HC0!v0%F8E1iZd|PMQfP{y;uCM+^mR!YHk%y92q;f9j)^h1twoG|rD8@dmz{ zw@RTM)qcfHa5W?iq*56CE)WoE-0Oc2So{P0D#2;VR9^vmZ1$2_bM1wNTVNAdzg@@A z#we4X5hkdnc8pjBd4HDQR-9w3beu*jB!OK-LuU2QSO45-@cT@V^WbR)!};9a<0rY+ zIdAo(i6ypk{oHwpV|?FB)d#@H{*D|;koClaqDjRtM+d>GH zJ#Lvdnl_%e<5}@b)`@p1!1DI_p8wzhF;;~L`!Z7FSgXix%xb-G+Zx9qmw*3$+O~<8 zYqvblbra$yEOzk^0F5xZKv{?(7RG4Wti6!qlZczW5YvolJJ@)JE7N;e0I*}mTy=9j zhJv{Cn^K!G05x&^c3Jl@hmP_t=rk+?uMn3x zHF0usr{>yA%$9|w0gO1J4S{*%R8#{x7C`+@xT`%aB-BVS!#jBBkcisD00MgPsLlE&x(nYv!m?< zL<=e~(z$<=kHprML2l0pQ|J@IF2|npw?tA8n6w^I09@E3wZ>v3t3;d~YavG}PCV z#ri-=Uv4x${ScI+bDo~0Vopk%3aUs~Rj2+RMtUwce1qTj_laCBk5Z)KSfDJ}TV|(v z@dr)R(sTb6=A-fBT_i~pf@A z5$AC?>rHMuJz^_hjw}Fw^Qyv8C6w4XY31n<+q)iW%#vaok$SpgWp15lz^RmoAFFgF z?~+7};`r1|jM|=DT%H8(Tdk_jU6Tx!SiFSaHj4as6&l{*69-EZ3X)k#ZDT)oHYgM9 zF8|eE@24Bey!A+)V#aAt#0fpGLo0I2j(vR$VLO%fu(xccb&kN(0k7fj+Mc#bkXnDq`AZ zLgBaH>h3Mu7p&1PD)}t(Yoo+vcP4RBo5gstW1HWwBltS$bZk~yXHz!@AZ!FXt%tbqLY^!T`Ns=znnn*=*g zSs5KEX@iMrZJu1GqR%%BYsT8_zBh${?ZC>shgn%TR$m5coIq_=92$KB2M->MSf%)& zEGoMUH;m=UYXZc^CTnIT#;f8T;7d`|0*dq1EEG|egi1&F8-m&@1q~a;!&f;N#QAEV`q|JlkJ>k7V-W9xEfThb4I4&M^k(cy-(7^N!b zuGnp?_ES&@$H&KSQA^hrQc+uHLshwm!?RwA;0|^R?OES*&hcfU?)~RNyti)vsA#Dh z`xL5^5|#_mO5o5Gm5@ww3#I_HqS^_N<&b=}x=jdx=vdD-QaCC9b3 z`zR+x#qe6^S5n!LXjoEgN}?v`?ctPtPZOneqfRR@tS6m?b4234Fmq2R-0k{rYTjyN zmSCSP0^w|D(0yx5%RPR-*>~7W)lo_s*9LiqaOX(L%I>cvF_&!c;^SHj8Bc!_3#B#= ze=s>Pd>ehJHHJ}V2r+)xv?~2bo>+wzTbZ&Vt(?B`e}*`s&RBmWv@Ov7l= zqbE&f$bixKEbH0o|A@8 zo&dPt+zQj!QPKAIYY}3;DS4YG(UNs%Aiw&NDP{)hd5=4sBQEq-By<|zj+DBHQzmJL zQ_C?(Ma@S<$a}?ZV#^@&6}&W%!=ASH+q$Er%su>}FoG3`@4p!ew{m1_ktTluQ*4u} z4)r#!g-TsQikO@giJ|2DZp{{93X ztY>Bt9TH|7e_Q^Y;L|Y3emgusIOFZ=ZEg;wS#XeK&Pr1(HSI?uX~b7nj1GdK2({P? zr$kJxFsDldVClAnDmV@!oWx`v<@r{9*3u}008$R8s<5lug$v6lVCIx;Rp!n@!PBE> zlyeoqD;GBBq~*Oh%*s5(MaewGUa)ahj)nPpSV6%gvSo;(Hu{Gr+l+@PLa5|F! zuG~B?D`20{fIYFXrAM3H=iXw+x}9+}+5gqo54TY?L?|?X_tehnV?Pxk?z=)rd5m(n z-$)wjpQc-IBNQgNAj9&X2_-db9#eclIN~A8L2AG$Sdge+EDs(ex5hXdp>E+Tf#Rae zsMNkx9HI>_J3P)#_wUqm`C!RUEz*);pZh{cG6*N}tR*aE#KP$MZbL9!TbsdY;N5~= z;p7 z0`l8KwQ~{67W86 zw~#i)=Wg!)VU~3t^mSaO#=!-lb z*ju16PGy486nudBafslf?;8wqd=yIPITdA3U*I_)L?sg!rY2yW7oy3M>?%Yia$r{> zsYl1IU6J7e4`DK6>T-fAeL+f8K!B`ozb{X63Rf|S$j%N4dEz$K1c{WU%)SgoTM~)j zEtLPCXNjYZsSK9Oq;iDK#S^23JalPMeDW2=8ih0&Cd=AQZp8d=t?dM zdBSq=T&Y!*5)NTc<4V6z1WklyPzW-ZuOQnJ{W`bLN6dEGbk?;MAC_sa^Gr%@1)-_6 zH9G#yleM!BKPtO*D~*!}Z1OPS3?m6{J^?De_4DIXQ929!y#xVsH3PUKxvc1owPOO7$$g}xc;I4&Pj_8ErQF{g@xj=v-*)Rl8b#&OwS=3V%*T( zff9W7l=R2o620GI6z>J>qgNu;S&j)KFNW#RckuK<^<(7nrj7~o*1x)#vzu%#DoyBO zcO%Z$XxGO0h~fwL?+-r}ehdEFC(MD%Mns97{=lkusD@UUQJA`5xQ~oxp(T>mybaLv3P!^jcU{Y{-S%~RM(kUNeH!Qeeb^**Ouh`MwcEB~t zB|0~4E%yd=DJ`Ra`KD1>maL_#X|bC6O5E||MidNU?$PDzdjF7W2+*e<2QM zM#Ae`H$>4DT?g>Z_ZPp`;q>TPT`#DLu3PQcj+7HNTwIpNt*oxZC52czDRjNvAzA?h4%77%66@t01ml*j=0)=vsZU z*%qAMK-xtOU$fC%#wla@!)jJk&RTYhRY~iHu0Og`TzoQ+|MtkpNFKS{-W|M*!+M&U zn&q3tD9orVL!6pgnWggc@4B5mb0(LUnVQFj`DoPN??a-saIO7EHdg2z?G0c<@EqK5 zm#U08Qu5!o`1&ORxL*9+KavGtK=%mk9=U1F#FzT4dkz0mp!3Sry(5Gk-CS=QNB)T0 zdB^q4%zamQ1MVih8fki>Iviks$ylbG*K3rMqBZ;$Q!w>cbzRkq7cRKCTr`dy-ki|Q za7|(%t)`6k|MU&BL*R8F$~H7K)YKTtW$2>#=^Z|C(AZQI`n?M)bK05YG_4zGqh89+t^9+w|tmmJvCT!Na#pw_9w?EjU|Y(+je7Ym#qw+XA?a^*yb z$Y^5udoX|u2Z|1e?brWevA;R*d#D5{o|->vQP`@$|NmSM7XIG7dv(@71QQs>O5lnu z3XM;@?g`G8VtW-sE6VTCcPp)i5T@4boixGFn>)#5nq351f#Im-R|~wU?52oT^POx_8+k3=%#+Kpa0qZW_*b( zuO+r`7v)0lk8QC)OSil<(SCwFV*zN1;5-i9*3ACn<`REd5;bV@XVx~vQHnM)=-yEe ziyEh`TcrrbyEDFfqaF<(&YKQYQi(q9K8PW)ocf8|o8p@Nnry4fQX4Xq4PK%EmkSFs zVVfo`ov@9y0-}V`O(TNsmG!fCQ6V{fqRx`jqEx?Y7W=LZGvLf~z$S>~(g)UO@!5k> z*<8W-ueo}4hOj~i?~4}Bc+5aNEMwVa2qH-M;L)~$$@1hYA%$6>2{Yb$tJZ=STDx#5 zS#|Di+84x>b}wIO7!BwC=+!OhJ4&Af#D%ybj6_SujG&oM9dvoUd>w40#2qEDty@N{XIKCV<2 zEJgccpRfcP&h%u+ZDNjhU1><|2v!ixzXqF>W$Z|zXA*`Q3t+`*D# zq_ruYS(`JgztrpFOKP`}=js>ecACIL3C?IIws%`n5`|rne@fI2cO$*9XpIJJ{fM>| z=^7(^1wMb?vJIw!_BvjSw3~w1<|40@9Id-r$d!{)Hlj;B2+fF?!d|Ka7p8OsLeQmr z`DEoE5SK|)tzD=Uk)75PUb>5*e`v^LZ<(scdkA;rV`B^ZPWE_1aAThw`$D{qJb!WM zyWzZsAWYlkl5P2=X0I^_*?jLD=1X^?T<6uDnwlEHG}mh(4kjCB0E?m=tfKrY)o}|t z;$ve5eA^73bi1B9l^&U%#z7ZhRHP%_ZO+N0P?wh zv1i@2|17cx=R#(+t_kv<0a$ulZcvTkIZM+IkXLqUT0x#hFL4B^R!VJHOU)Ju#}C>{ zn(&vlmMx8tu=!cyG$+UBDskZfr&NUB5^|q|1BVY`yS>@n9wD*N@G@T zgOzoze(NtW9VA2v_F3!7z$V_BJIgf&Zdi2xC*I=0@p~P1uB_@X-`|aULC@_+l>uY=8 z-g64Pv3Yp%b;Ow}B_mcWAZ%MzuY2HvjVZ^B=^CCSS$Atv9go*Lpi| zuzZkWpz{C|KI9ry--Hd1OcRmKz8X8@uVX=!P1ddgi|_R3Qceu<*DkW5%% z6JrEaiJBDiu_QjHyierCYh%}s95>gQ4Zylf)@VHwC0URqLbw&*NL}CK?BulZX=I!B zyE3FR(`?jrjrbbR?EVDA;n5Q(p7xM6f3z@fb*tv_)h`?ZnzuRRRe6)8l4b=;uIk2? ziyEhzTLaCG>z?1`x3-TbdXAQ021b_zRtQ!6n-WX8yGa5?PFtDuBFh6vf;Y0vz2cNi zcxU8FIhdKx0G`1~n#GX1IfU8;pPY2CVlS0wrT(3k6R)Yw*JfZZ~PkbB4;qd-=oY zcWfCExltC~weD8P^3)`3!x;U6>4s5@{K@Nc%42`6T>o)x-kvW0Y6lV+UM`z%!gfi_ z>|)~LupR4$Z)l$X{+$b)VUS0x+Y``1%fEgpe}}cIy857yafj%`G|ZdDv*io%R&qNr z%--`G3ZL1x5N+0|T=ghrF5&&(69qX*$y<4OO&uMZ+Feng3_s`krjc~pt2L*?gG(Dz zt#Rdi-NOZyuvIW%_;$=Hw$pbV%8tV0PEO%7ltpt`ueQbT(~|QX*SE5aVf?>80L4aM zXG;rZROD}#u+1(F=CZ;yB(sVBhsc(XzgEn=pip$`^(9wT^$@mdiJ1B2eAnYq?`Ct>C<_-AvQzO&?ANCk6-gB3p7lzsDEa>$ z4Z)@~HD=ENql>>$=L_{-$j+J2lYCPa4UF5~L!~8)axEf;D@W*&K~h43sg2Db9AWh7 zA;VWv5#73L>qj)#w)&W28_iJ}##a32*=VG|OGP>P`#FTP?l`p>k`f(v505}nLmR)0 zUQ`G1h*%EfemSZX*!iW0>LeKsNrqx7jS!y@CY&N1ma`D=*?wvBrOb(W(Fev7A!=_J zM@Kt3DfYud_uhZ+DN4Gr#1up{hMjX;$hvdXUzj2v0O=wYjtE;eVU7qmGG;S^AU6BW zPceFZhJ^u2$NYyVYnt|L42lQqUd??tV6N;x5639Q^WV9Fy4ut@?FvAEhcz{VGJF^k z;P1{JcJ(GUv~a!Yw^7yG3ilhs7uCBHI2;nZg^-h1YOn9T^&jUTcm9+PLAfNfe*pJz z2iV)BueB*dP9M@r`b(uyF??^nwi&d>a@|9!3Ibm78Wj~4G24pgl#lu!e^Bf7uaR1Z zPM{@9uQw4XEOf-z_{44Z?%fs^uQ5c17M>c^k#MLNU~bTbnzR3FqTP5(YO2Q1v@@k8 zkXQf|9KiX6Sucu(#Dc2-{y(~@4$wPxWu!OzSOvz<-H#D*)H+F|sk}hAl0!c$9zRR8-!uc4q3rN%5KXh`OIdkSd=|-x8$`KhQZW|1^ zaPFfO*#-5(=qQOOnI0jF>~7K{&;XL4gv9*o*xaWye~N$qUbLDiN(mEP(29T%f!!w} zFP~bP2iLm?Jtzx1It;&wtvw;p@Z8M~YvH=^&DpehGsw_R4i2gCHa73!!`{?n9r1PQ z%$f?wQ?UjU4#>dZUj$Pt7>t7&KhV=d*r>UR?3r7fv%?!mv-A*PIq>Ng8}|kx$_|BL z3183XehSFhHO`HNp)(N0lCQgK;^IRzKKSpW7JTII>feg(dmjk^$uV zPoMrm4m(~5uF4f^=QMhh$n~=zcT;a~^6fjgwHQu{<_u|D zO)MXH4j`Nz)jvKULQ7?6=!?u+fTB3~ozA-}a>tovuZbfHOG;>{si*r&ucfBG;wq_+ z3(hMjsJe-zVCRZ;4OR)u8EhkX?dRRyr=WhexpNy^E9T69@7Yyv20fBkstwzj72 zs_{bSE3&eNF)swK=k)2*`kjZ$av7PJDo=C^LIjOx%s~ND;v1Qn{xCjoyIHJmY)oTq zu%4w4n$8{Uog?l;vMeleN=iN$73fza66W<<3SuT1ZRSbRj-6@PGa$>v!yU)N{p$+x zWvK2gLQ2H*!^2yNBwfQh50Eev8cM-e*@Zu+%EEG{BSiu)6wHfVyLKfQ?c4Vpww-tP zpW-iCzAz+Ad>fMZO|Yz%78Kt5+Cj@aF+tJHjc(l9pb14H7Rn z@QhfLshVfHb6c@ry)hI-o&fB)-|VNudzHd_jfsgt^;j==7xiltpu6Yjma0;Ze#dN^ zXz0UI)?R}f#U{c^=m8{KgxVduSWx{8<}%n4t*7OemX>5Mbl|gVi3=jK$R|F0Six*( zjSz_zu-*JZEbbd3g}*;b44QGSLGFG$7h^B|c8t^@ZgRhy^aOnv{Gt7SeO6ezky?Tq zfs_YPlMLqVW8bBuJw@EqDqUPkXJhRtnnUV^>BYZdD}loYz=w^roK5B+ z@S#rqu$-TQes@fSGp-w=-8*nYd*l_Mg8x%(?f(S3KV3p4>m7s`P}_oy(uV)h1^&k9 zZb(LFzr#dA73$$XGu*lBvs*0a6T({`n3)#n!;ArC?zaGf?sC!F`-vSTIl1&%24?;C zW3}G(DNh6RNow+~R02yI^|q*V#ZoLJmSm-2gW$(?V!)0GKS&3enS2MFVEulUC#+p) z`m_3_jJj*HiVAEm^(uo%a9Xg(4%_eU?jAsDu+!X`t_(B>r_Aw96H7*d)JMG`SgN4* zDC0f-;qnJqO(llj3=J>PgAsj)&yRV^!uYE5$;!=2k|QtZ|!w zOkit4wi#bLmIHcH-g}=$N7pyc2=SK@DJy7|)O@~aA1TzoE@-gh;7pSop#OR4L|@+>xU6_l!Hjt_;$BEdNY^f#{Eil}oYx%#n>d)__i1IR zCb6=}L42s9(gO=0@q7$??>AtY+8*#sIa@SoetpB!^8uOR@lFuQI@4@HDscrqS|s_EF+7Zcnu+^d+P9Fv272+0O9xK=9k&*1{Z7(EIAsTe0o+d z<)Ygh{RPjrWq18w$>*Y=gY#YY)8E+jAEU3uVienZ_25HN?%G;vYgHnZM4!4+(<1iq zeC6E%oR}By-%AN|W?cJWBO@dDb(G5>wJayCtE&VyEWOA5ME>KVWadq^KX35)$I# z(h3T#U#qKk0@rx?b728oKbayQz>V0MqK|F}4 zxNmNw+2@&$ThBy+I0^+CuqA+?yycB$9|37m1rGO8J$n8>@)?yjHTpqU&Km- zhMZ1PBbUVkm6p}Rj;|RiK1rAC0x`eGtak2kpY%4(OTtp(gd+(+_Ep2QSG}mqF)3A6 zRD1#ZdXwvF{wtYx4hbEjTI-D zwWv5teNaGPDq=f!&FxXWoA2bJ&7ngS1^YfRFkGE-YySbJ431xzjz!QmiE9$(1b2$L z$p1a4i0v1h!WH74m&MsQzy$)Y8Wx1qJ$7#1ym`5gHj>x~5+l!KyqO)J zbK}m8_}m|&_#dQ=#==QBqYNeHyWX@mds~wQ>bPQ52|3eqF^6wO6-@^ zKTSS-2mOt)S^KHj!=ts{-SAma-u6o)F;e)_$ndCif$){cs;oIJMqflUzi0j+a$C*p z?tQ`AuWi&*7S^qE{%)YHaWHGhO2~6A-vO1&jK;~}+nPe&#=e7{+r>o}(ioc1TR}ps znHhQ83tR#aK>`2^=W*LcnFeH26dhjQTIav$_2OxY73XNIwBR9s=|&_ zn&}IkLdlB=M|EYqhwW3c#>Zf>+Z1i38FC5i6oz(8D-x8ng;>~_VrT_@MuiT%*w4R} zbj%>Yxx<*ueD>Z ziNJ*{I76ad*tvW6MHE@pA3#o>+XD&CF(G08`H~GG{H2t$6Jr~O1M);i)5dwG#t~;U zetTeQ^S^I~?K0a!6 z%3B$Fl+WsNQqp=6%nEhOqu|9rW#mf0{wK|;j9ToN)Wj(VMiHg78ZzA9-|zcp;dP#0 zV>Q*`mh)*!3Z?eo;2=hqZQFgD;buD8@sU_A-4IAkPd_ux_|xjYvQe;dQJdqy z_CNI};iuGs2cdX-@p^iCWb#i)2qT_5n3^UWmPr&E_JXS}AACmgr9)r|W!BuZeX$SX zN<`}jd>Mqhm3%jS?zo=D`#@`yF-{Zaa3cKpzYc-R#g-k zxfo!&(d!8|zky1JXhjw>K^G|6+o%{Vv`wiJ%qj!j2kS20(+wxVal97iQaOcmWW=Gl zS7PK`F=B6Sz=Q>dcA}BSHEc5a*#~9nL56Bph}#tMX(i{6f6wv1d#>oRNafT8P0jV` zR&g!+&V`1A48MDMtCTZczh}!oskFBJG{>&}H`QEJL=9YsCK=)5UXkc&avwJFo&lzT z!zUsS%h=%id2vzCGnKIidBD=uc&BCEeJ5&c=+&##M=scI$3OZVI`j(a4=^c88I^w& z?8_9SPxxxG5b*xv4e%HXoB1aJ*InJBclSlWgBe84D z2Az-&y@|w&(lpvW!L@2`^m98?gSVUFQD1E;r8g8+mPpMmzUyKyXmIRA-J0fFTbs~a zYb7i}uVrv!q>OPpQ}hTV4Zu>~vm6fj!ali~pAc%=;suK=66^NK!mZ6FL&&|JRNm8Z=wO1NXMrm2cM9zV`s8bE`{qzTfPK^Y}P8expb)|(mcjD>oeDKRL)V2`L) zAYHR-8(TI}Z85JPzBT4&Sa_?&`!bu|zn6yVHvl)f`=4907*g|EC-`l(>O8Nhnf=m= z|HU75Rc`OUyt%Y`-tlKFKUI)E8?!!}S$zP>oS`ZxDoDxcNQN1UbU%6xM8##CTYybE%$VG3qFZ;v(m-cso zG&p4Hm_2BVuexf$F?Qr@h3C?oWlM!8A?#17_$}~Jv#wwt0Hcwws4<4Gpw`%KeRl?D zqwBD9_qJD0cjezLsIH2xPI2svf1uMAKkgY5X%BONF1J@-d6iTuNoc(9x!fuH`GYkn zMJ7pdbKRs}*^Ys{pEI$dD_=D2A57ZGVx6DUoS4irBhqAQMfbnV912Zr3Y58%Nx6yd z^NA-Ha2i(V>39fde2UxR5H1fPK)~QuUf6BP!Y?6|>4(#R{+NJTmy4)F%o+Usj`-)5 z&s%{x4r9k%)H0`;rkG}DQeb%*b%8DX_H7hfmqM$cSMHSm_~yd^uZ{WbqouFYV&bd* zT|Ye|9~mcj-fjcc5vb*0z(*=_7se6zBw@Yqp| z`X|RA-}M3Z_LF{|2U!+&R^tf#Ea`FL{{DN!VpPmYBH8myXvWuO@yB z_!dNF1%(?ALj#tYl$3LiW<5?R-MP4#q@Tmn`cvq@`{T3WgeJaq>yZjlGX@&c8H-s& z6d>g`PGDBL)9wD(LtHR>eEym;YuD!@{`Kgb%dIg#oW0TP@O4qqI^?(h_SQ5wTi5H& zn%9lc|Ik_V0@yZmtH24VV3skL^J5YZMzSx|e1p55uL9}o?%4_FVlMXNOTFy-HDd#K zw%!t0Vc3@e;15De!Z*@_xv<3Q&L*KSi~0U`P#!hku%BzVeQ*kS|cipXQ(F2N@p%={NRzNR-c@aCw54>X@} z?%*{@rFv##e{j6j@>$+H50f)n4l$1Fc`CIaY*$ux_TESPnOIKwpq+^ogi7wV^}R0} zjV+rb&I=!66WOVjFO$gUB%kcr>O=i3-cmk+uYH1@Ia2uA&^GvB?4>xQ#B?^ln?C;? z9#_f>?ipPzzl>ML_AU6=^+zez{&m&;`!JH?iaq6 zM|+2^U&f)3$G<0b0J&a7aH_=i7p=f-P~3C1AGfo6q3AT0{6%ERVC^cB_r4F&_49iK zPzJ;1>(_0xwVUwjnoPB%PY5#}V#88ogqW@WX3fMmRO*0fPNTHLke}_!rA;R?EVisY zGT)WoO8bp=!VvHHU;ns`0Fdy=BeKKPh1z!}@Hz2y!t7^wd_3f;=rN+i2E4poo3I6g z5Uu^$GaZwt5zZ}Je!hOZawuY{?SBdCw4D-M^GiP?XW6?wk>JAvI?V1ME!yjGJR}y+2Ziwe&EF@3VNX@1BQscg4BAO zcICu>{X*p6S+rn7w+?u!Uk7$6E&9u$O7MlgEbVyfoA5xMbLeOR_uVT7sgX8aXc-)} zp59(d8kWdfCi;p4PPT38SfM+?Z$w)+DglZfs}ggW;D7yjLZAgNwvVM30)246!{^OR z@a%MtPK+EwOdi0m2ij*v<>U_dWn5ZU*!p;JG#UWp90yJLDj>VvoEXmnXe}WOHcFQL zaI~qd%+dGx0Cjls-f}j?kJ5RC_kHpD5hUqT&JdY3UxKa&umYkecJ_f!* zEgV#zFYev28BTNz6&kYE4)^6)FXG)~*u*_}ES`xtH;jKMS^x=GIbYF(1+5%c-y$6FL$jWK8{ z5O;Oy+j!)ztx!Y!!dx(XtH7U-e-HCpEVa(cXE%ST?c2+&?`v%~zL2L1j(7r98=xe9EdpEGW zZ$K>1ethZS?hbb<)H*@z_WV1Oj5mB%{Dqaw%FGKiZom?`qNLzQvCxh8avNsLxpE?F{-wJS4{E$R> z%oI$MH!4J}d-Bz-)N?n!Bccch{7Fqe&D~`3*N&=zSomJ;=(^%lJ$clXtg0Hw@y+`Y zwzLL3K@z!hPk;BN z#Kirz$c8qMs{-|e8}p@ z|Ksb;+SA-zMs$YdS1W#uU>bjbKb*s?Q8F~*IL_y{+E5LIuWkneBYV6nfti< z2AGQW1kOUsD8$R=HaIZgdf?qHBcTyMp=LRxit_TYmjvSMP6veIw3`&18L(b@%QTzQ|84E6~8 znK72I?z!_-!!Lh&_rta*!G|ze{PSkTusN{-bA^t9YLzsEd0kZyeQ^Eg3e#9#w(B4o zRasHnxdPX4ee337NO{dTQRgP|O;%c(u#m8!5caCmwJ)|kHvoMgM?IOzcuN} zp|d7-9v;^BNOkx4&d=O7Uk3BT!tc6g-Q-q_tnXMx(Cm9E%DgZ2U|!PjM2SYsZjwai z`;*n94d+={PW3|*9p9F3GHLw9Aph*oaHHawd}nC(a@WA&_hux3v2lKLQ7=apYpmPO zf^pg2yjw-@Iy;3=tNVS8#~XFz@ok&c-Mjz%qNk_SLdF(Zi@|(a+fA7-$vg>&k1#kR z6P}^BKo;7N*;A&_x5+M$ry_5g?*Q{2eO~n6y+7lzD2Zs%6^iQC-hqMYn#@&4-eKnU zn9_ZdO!NQ4LIt=vbE=QOxWf`u@jx2LM7mwk8Wl|}Pt;8*Z`eueqf@R3>>(0Vbu zv*p5(kl34|eOBx5k{o|Lvu4QUI@kwvF#i~A&Q5$kw579i4HHw?K7A#LGCQxjgj15k zQ^YW4)Am0{U}2;k?$4GFQ;hJe#M8oHHv@U>9<(p(>(v37rsP5~R`Z}4U@Eq%7MmnZH0>DaXm4I?vpjhIn2Yk)d);$U3Vqv#kO7Jp8bVY5PtL;aQbCfD97Su|*99s5r-PwcX-qJX`$!iz0k z=IzGrui9GkanivKGV*vT?q`Aw6}@_{kDPJbaeU=5=RhD>3^cVrS8b+qzVJ+@pPsrp zb?XGHd-#397R;}2Nfa&+y9zOa9lEy}#To(@$6c6{Nvaz*fQGdl;|XVfUEM z)*F-sKldZ3^I!?3vR`Q3Y(h+w(Figi=Z_o2POoNR(O28dz-#Ct_HEi%SEyocmZ8xZ z?X@|{vFAEQ#v+Y}x7RLMn2cI93F@SF?_Xi}Ra-D(^cy-Ut?3!T{oBuknq3PiLEacj zI`|G*qN-vu&2A`c}l|vf2|(pB(#E59+{=A20cM?rh!}>MSZM zT1-ObhBKyZ%6n#%>i-HGvyXr9g3NrX?F)S+hVjC@IY2i4E|!s7^wm~J6e*|0H4k0b zTKV*HnNR<2_ivE`n6$3`lPQJbU3vJ9p(7uLBhKN#bq1;@R$n_v1(#^)iR|*}U1NST zZ?BQj(N%Sa9=hL7I!f*^Fgas=DT6d{Q&;PNu2j=aoi9}9j~fea$;iqM>?x6>*gGI{ zhnjbwmDQR;$+h8-6lWoe8=o!uQ0du?(;z!!b`0@pWlYfVWGNc?3~ zU#@JF%egt`{sK-aZ?=skDQD{4jZG8?R~vnmp)oSb1Mr8oiCR9x)RysoiO> zU&^|^dw4hF-eq3SKf1$S>`_KLc;bd@B|17R`lSYu(dSRMKQM|zrgYWJ`}!KQ3=&)) z$4(+imWnYRvM&cqT|e-Ig7R`9A)y818ypvtul(7k+C(joQ65C6hmxZ6GV4!YvT-{_ z-Ek)$drO?gSN&k|D_&$Ny4R=f?0ar^^e92ufSL3^HxvDnq&I9cR#G^3B!yDFb0%hN zWr3WfOBho(EX_ZqZ=LXUSdfy!_ML9ydow2#coQBB`gMStbs`iAY=P6aY zY?#qROp1?!0nX~1HlZZ7D==G$SU1hpD!(C_bTsG-FfJD#p_ozXYpG;&DA!%M;38TB{I z(i867*;E+?2!b+QecAOuM()wX2j4^Di=m7obPzLnm`nvh%OXhT1yr!G=cXQ2y;-n| z<>|bvW!64wq*`WbVszYIG6I?LxebK1zDKa&TJSJ@LIOu7#^D8N(`5CAJ2{ddDpt^ za#V^hxD&yJ?9BXvg7<#?Lcjmx-Vxp#0zu`VN40;bx6ody`_J`RsfK2Jw!QGw&_IOw z(~uKebil*w0)^ z6mc1?;N2ZyRsg!caiHRP1aOpIDo$Vf=;DVDJ>fEg=sp%#Cro$yqoHWt>WRL5C!M}I z&U4pw7q*9>a7HwUlB$nn0jH`gi*xU0?y)B8UFe3-}*&j_Xp4_%FSEqe@;yq z@V*eVp#NLCT>YOiDeCwZt5S9rw3|Xg7Kw|Lkcif1(D|njSK|CzQ zE`N7J?H=Sm^UHn3o)ehn%KFD&RB}`QFmc;q005e2iiKMH9yhmqv@`vaZ*nWkLE$Jo z$YElbos+}#fJu5t{|U;ow^O$5$t01Jzy9vqIJBv^%F1H;Au}`cFed70y5XhBs3y{n zCF>rZ6A{m-VE==S8T2&_43pa08)t9fl3;2!E;sVUfEnT|&E-1}9qLA}<{-bir3V$R z{R`^(uypg;xwGEq7Aq=_8|Y6>3A7-k`ScB20fZpuk975ituyxxm3V)u29AG1t$f|^ zBh(5tvUzXRc}ui?tx%A4b#{(@h!Q7O$9|lsi!6jS4!k0Q;-B8^G(0#4_kiLnE|krr zK+!-%eK30{V{b!vgRI-LlEB^)oHi^Gm$FE^+txQmL>8QsCc?_FfNrS%9v2nBn> zxAwb-ukaG=pns|l#*-VKO*aqRaJb)4TT6OCuws=hR`3#m0*e0NoD$62s5R3EnN7bW-!J!%fKU;0KejOaFe;Hig z@YX^B#Y8_%k9E!3%t))8bJ}q~BU>z4*NCarwb~!J@bO@0oNzw?pox;J%u6-AjuA1c zpejV`#4*DLR3qcfQCOWc!^FoumwS)vsq=HUpWiw&D9kM$rFF`z`E93jjpwCbwk^*k zzuDUEVCIoqc0sN|?#vCjFEI^$#Wb^?mc!#$#{}Rp9ML>}fPv?GwzYVi_H)@1J@YyV z-e;ax)AFk2n;clG&5ghZKH7GYsiEmuGZ>E#ddj$x&i_4B6&xzHnHj@ewk~(Lv_)zt z&N$Fb%U!I~wKXb#1^;ohcuPs7fdun0GrF=V7}o(;Fg<*iGFb(LKEzobsM$p9L1W`( zQML#A0Jkx535_EmMC6h75a-=?YfYnN@PP(EJN0#S6;*Tf>Gu*M3wdQqZpd7WjAYNb z7z`vYzwyKeU}E;1!i5QvJe;RC{j6ok^^7}6OJ?ASTO1c!ym|N`g|b6*YxyqL^QsTo z7d!z}m~GQ%dEh4T&k9f$6}D z&mzP3M@-ra!_RF9UFPZ9dSm%_hso+=6wybHZ}0dNt4W;MF}`niN~2KP{G*URDj(Lk zj6dmiqhKZGrIxK;+!>VV?^3F&r1T512hr?RdAN}F=j-wD08}{z1oBfiYWu{w(cs=N zHs!Zw>NOBgrAxbc2jzQ(O;a)~7^Alx*GGejpNHpZu93JI8F^U=lYttZKK9JDY=zcO%c1$%{xoSR3Qyj-UpdrWvMJ~lcxd2?4|^DAUBF`P zHvE0&@$Cff;l#~Y%-j{!Hi5#-6II=KtrFt{J93leK#0qLcg~srku7q@@A*12Bg$m;>d)%-3 zCTtixw@F<53$XMCzOd)_8&mrZy?_{B^UttC;UmAL({w-W)Z^ZdsDxoPnyn;}myJwj za@m>Y%dywd6t%62^s@tZ#8AN``xlx~A*30TXaN2jC`NzuoXE^GI4e#-51Fjaf0;xg zWoNH^vvw&IjsLQB!@QtvnvOt~!66sdLo7;CPGs($mIn{`DslwtTwA6sxh2PApG#h} z$1I5lG^onv=H^PAzQkup6!iJoUz-WYrA>zuoAN;U1)rU4- zENnLJZq<{2adFM3)1rOBA+r~W{i&UCh?aln$x^2*JI42_7ki++6WMU&T)-p)#uzfl z)0rs;30k_>ZLZf#JFDNxt9#B}<_NRT7wTLw=Wunx9l~*Lcb#a=7;@9gVfH0Fk~u#^ zbCwQCsc}?(N|2vsO?Q5{#*8;NDM|!JMhMQqJO@)$^=SyJtDCYu2~0 z-u+qx5+u9{iu1?=eX^U3Ac}16Y}{1B$)`TP8^n zyV41Hfy-aa)!KxnO4wx;Bm^PKIAn5EY_4~4{)qc8p22*X1MQPjTyL_-rTJ|@`iZhc zNJX;^ApFf?{oNN|FI$=U&pp+}QzD~(_v54?TwD(x1`u&Pq@L^La)T31tl`ZJ znF^$d!W4)S{Pdud`WuO(%LLqTAS#D)cBCOUObVl`S|5lhuxpL zc!Tq2_tJGqO)yN+5$nH9X_;18cEUGC?bF8P_EJNNxYRbsCvRCt`w zbP5jEjNWX`{aNGV;_5pxLl+2FteOo8Iy|~gac=r|>rK9oMnZ+jTT2jQtyN`YMw}d1{BxJ$ zLat9wc0lE&SYA;vUWoK@e?mgo2Wf$`dPbwSKS*tX1wy>cP->ds6Nl`GWj=3Ev3*EU zmoHG}Qm+oDT52%~w2$g+v4WCOGFXLcK`+MSgyE{iog!WurzT(qEA zeZNDOT4~WSla0R_3cuGaq4t2PAq^#`1T8488NeKz0E4eQnoSYi5 zF&SegUC(NZ9c&~({o~%=gkn{`85M8YG{O3&+C6P?d*Cb-0-7~*)8CDT6 zPvWs#>Ph@ZR==NyVX|s6g!9Xv?< z;(yl>n;nT^MsQOB2DSd4-|^%6Ino9^|LfV}ve0(Es5l9KZmH+|O0M*jh3`ie0o!S- zKT|b1eHF#W%o`5Af8GQ>-SvSN+${_j`~Krc9GRGl#vRHmA|j$asXz2}kBdCy_uwhe;ZS zy*$90M8EfCTiYa(9y~=tXp|u19QlH{Cz<^;j2fAknhKsAh)qs52jKNe6VrBi99AO@ z9L9@YX%s5C`rJ$dejWac$omLS$1R&T+meNZ(g6lt(0+{(W4OKZ4VM4hJ-;+1j)#Qm5-5^*5YSTXa|wT(Y3vPT}wRCH_P#zd`gY*VP!Gv$AX`lp6&%%j7R(#NWT#*{1Q_fc$=JAF=|dt zJOpWF$ip8)GHnS#O|*7@A=puvbjGyrlQuj3IAemmgij61+8ZV)wzQHlwvLobCdiaG zwCR4&CJINo#wL+K)$#K5T!2TlDjNEMfnxP!Bct`9jagt^6Rp&(+U$BII*ruaM#$EQ z>0hwoX#mge?OTjJHfNUEAfAPGQSa&L)TI}F2rn9@gjjoK9XMTpU+7)Cnv^8YkX()Y zD&eXPhKpM5V5c|v5U(VWj}EE^`fKagug4CUeP<7K*JfGSeZw2E5Y8L&a+<3RjT6hT z^x>mNJ97y8PLiPzR1$XU*Zi|sMfTHR))Isuh==_K86K7acDNtvPy2XQOl{gy^op%= zTO^iX9ho$!WrTWz-6K3!IL1)u8{b!J7=2op<)RUML3=dx7R>(- zF5SsXEGo>p0K)(gf$~s{dFho!K`Jpn+UV47p#2lMYm4kvQE-4A; zuUB1Nye>|#S*#UiK>>KU*g2td4<280g1i$3*dgwW5r!Tp#BrJaQVbQDrKLO;^Y3~W zB$k%mfFUm-n~RBzq{=%oWp%-ffJZ@5(Tq8u9!TQ4&6dJTODZHQhLH}PIV}kZhLVR7 z5j#Otz%H#7PDZr^<_BcNhn8O3Jbo8_N?beP9S_PIU<15tD3eHrD;@t}@739y6JC93 zM~Tl2*Co76_IATq}g#{EK2#YK7;UFGw_s% zQCx|5J3@-(nh^$6@k7_T%(?-|?u;eI75$*jlxHNDT@>`*sMWLiRkJMc8N`qVwWd&VhT8EpxdBNg*br1 z4DJs;2;dKk@eIh7@{ zH&|B8Rx8ix2R78+Osh<5rn?4>&z>N@aaMT=?FM1TCbU-(#9#-a23`|-#Bg%NP*2F= z?z)nMHJ_<|RdU+3>-pDXnf!_;QXaam+kCLQiuZ++ifcCyuhi!{b9M*vxp>`1Dk0m# z*@LBshQW<}#dgGuOG*NK8G#GdO7g6-rs#xNKRL{9YWFYeyP@Q_Fs&h8ulf8u+s z8>sXmp-BY6C6KER4QDXlA?$cmTpUJBCG&;C5y6hs?fjL`x4qM(wLi!Au-|;{w2UV61|sGR?EEkNZ>iQUwiQ5C{SJb z1V?rGd^rN`ebRX!;IW8ZLaN>vuqliz8+zSSU-4Q?&-g*~$*mPlt`S0zBn-W8@SXm9a&n2S35gfX%f_y8Cg*qRQ#j31T_5Mz=L;cS-jx0MQ#kYot+O~tU$nt+E?xjDi7GWH?^Eu7uWa^ zNGpkS3~5i(3#=H&1QZFKEFV*G42`XSy@vOautU6(6H+GRZWvwymR29ypsZIib-4Os zqB^LR%PSexcAZ-l$ifyO5Hj6c#b4$8`n>7m7fcrP)6RF^QvE%#a+PQ^g*KibtC}Vw zy`zI7HiN~c)LTS6d*p2L@2QbH%`76SHnXBPbv0$V`c~k?%|C0Ot^^tVhIQ*`bT{^i zmjiEg0`|o|yMNirNoAWg`rBGag+2?tXG;-w?E^QKDLPO^Igot6d9zpx}b1*C6p&-ta?6gb3-st8r zfRe|OZoqNddD7zvRl|{lQS22%$#s19~^N`Ti>J_jIzKrpJlo+O`} zS%&Mj7dU(kGS}kpc3M*tGjA-9gF`Vb-@_!ZuPf+TXw}^Gk!ot!EuZk<4^{yTBUxjZfo#zis#%R#oIr$J_ryN z=ZK&oFndEDTN3pSErtXWS1~)n=SM*@f9c15axV_zt3`e7mr}b-A zZptHtyDP#eM?+(S`7C;4#F(eZ!(~L#G1-6w6Q}U1tzny0w{E=;O#SQiZO2`~Cb6}> z@#EBrzt`$bUnFUEN^Z5X8V_gPZ9Lb;`3;i~;50@$dXJiU$M947k5MY%8+Z^H3o2%f zL_`^zx&?CmTBTQN{>~T07?3xYKpx{Xhq&i=e7>9?c4iYTJp6fi?roF14=DWzUA6pf z;G-=-;09}t8=oLJ{`M`(ef=}U*g4BtL=CK6Ru=alUMp2;e$KOu$Vl-F!`^}kg(Pkzp6{@@|t5pMW_(vMNG z+IFm)zVRt&YTCS`GiLqHXF7WGgz6sodh+hw)x97!KlQ}6utqZrq$b!yJfkzV5Yr7? zWs+Po?EVT7Z|E=OJ|{O1foi)bJ{=p8JC3G1*YQe@;i0g}Xr8~%&rl9j$@A5m{N)cG z_+ps!wiCm^B(D0j)LR`X-Zk2#zjy9KxZ$TD@)y71;xQaJUGLtxtyDq%`r(d3g5w@O zQ_Xs_b_aGBG4&H+RN zzx;W1Ma7>el)DYXaWeWe@Dc7JINXsC>qfcaq;_+=kO#t{y!_j_FV~-cS2=Me_R`4x zkV&@_9D(Vt=3m{8eN{1l;pHQE0nsv=pOR9sZoXbFY#ONq@8$kSPGRS{tRF7)%EKq*Eg`6&ab=WrD&ar#0|-DaNBQXPs0XHOwz zC(O_nTvsGRo%HPHTx%O9V{ijQ0ECjBz6f=Qhj_p`S*zS;#pgsif-5?=NYr7$y*poM;W^1#9f0KiC>(@gVezO#eFrB@tDBHGei`F(UcuQ5(a&pv0bmeu3 zef}~MhYt{WejhSUVt#&p66_`TOmC`nZeslBbZZ)|TI{K={*1C3BxQ6)A3k_cbAKx=vo9+-aV*7ZK^gF7azA&+Y7OORF$%;Pw>$f-tiUqjl+PLe`_BnK$i3GTU0QEwLjnas{r5L_reFOidm&8WV;c_hk!$7N;U z1_CxP#<8FD|Go~d)9yLSq8ch}mw;;`6<`mIVdQP|UwRF6F;UT_5Sq1G;Gjnx67S`7 z^ymd`T3C$B_P-AX9(cMokKu6w+bf>7rY3i^y75><{@-t4$d>JM^g3}o@tUi3V_Nfn z|2>i}2MXl@0w&-HHa0dmp}^ZD>c4&k(}hlA)F3IrRvFkYcYvQ?F#^KBMFDOW!5A{R zOc^*~jR@l;;b0S;Py(44?36$y-0!)o3-7X~|lARuEzm1y^f+g&^z{!EV z-rj^)Q=KYzt+Urf1sDt##i9b*8zeu+>J0F4;q!&9VLU+rmbF3vt_lpgu72Bj=AX4e zHtR>sf)rF+wjEbA&zCSonuP*YwCxhBfbo%GcmU+;0Oa5oTGpw1aRu|x*#j1JLO z%Yq#yqkU5J-{qZKZ}`OC4y3cu4woB%jATW0w%)_qr83|b)95-EA2OMI-=-qoTC|IpvA757 zvO<1amDA;rFms*nehd%81`wYHtx03f@FveF2H(Koc*~W0CSFhPG?SK}kgMLB zjKi*_vGFt89oE0sB73NK^(kYxFbT7^_kksP`|zWCSV+4SBqka?t^{ujplda_=rn6Y z(8u@bonQ>C^dDbAo1U1^G1mkD|K&6eyHC^0Bcu}KFuUH`WVHE(CyOGA)(--lduBg) zj&oTiYqh^X2MX#2@hOYte|L#hWsq77qlr$coP^A7+z)mv6kxqAET?}?462{bj1_F2 zNGC*pMU>7ls1J!JhW;03z#z4N8YA*O=W@6xeR|e<1UoS}*hiYye(n~U#=_Rzo~-va zZr>gRs=;ni#N<^scmMrm*y&6HD@3Iva*ZIYG=!6?K>sGabWU<2KNlcEmZ8ki z=4&O$)TSowQA7mF$ONQq}dIe@C%LnAjA>^3%5`P89(t9NB&8`T=_d+Q}a&)>;<4n zK+1H;30?sX@?eYUf~3%+<-{dUuvnt0Qte+a_c#(Z>uj6)7?t^^JDV zky+eefHYQW_zcsA6~|AW+^MB9fHL#cb_EHWaWKF0>xC&YL%gZP`M&u8X!-Ft)(EMl znuNBQ7_*$j7yF|}ANlk*GIB~-9z1ySDcEM@DEtC5rLh$c4rW&t7q!5UM?ykQkR$vK zxPP?^3C6siRH>S6M(%j31r-DgsTzfbfI<9{e`(wM*!QTF)%Dh>Tl6beGNz`}|Bc+* z1g;T_D5-coHMO~^3D66|e=HNui2W8(P=(7%eAiBDp3i(q@!JP}wkH7A904F;Nlr@vm}k zkfP+5PM7n%3fr~?ppuk&4qGOQr>D&wi!EG0CSU!};X)-iiO`;5sodOmLURC;{aWEn z?SD@%ISK(nA_@Re2Dk;&Fl}>9`0|k&oa0HctNvaGN?R|$T3AMAW=S}iV_;z>!NAM% z?{Pot({2TA`-x#oKR-pcRV!D10N66$pT1O{+7^(|FvHpc zKMVvfSW}~Z7d7C)Q=3GJ0?mW{2r?gV{hlJ}P=W@wp`jsNmwV%;O&6LyqZoW#6_MdW zA5)1yi}d8zXm7gKhIFA>)PIfA388U~4hMtmJH@@iby{e5w3M$Xz-c(&(jS}n6 z%#5N(Hy2Is8X8Hl(fpI3{$bbbZ+8p!JG$79K~3~7Vr4SdRmSu@$tOsvUsiX4P7nx6 z+02FGpS`ewF9~aAOuzk|8F}?SmheA*5%*NsGZ~aCLug^DQhRRgLT(zfv=ULS-+biO)*#e01T?E*>sOUF_;lO>Sc6A?^s6GZJb~My+mMF~*8`G}8EVOKcfE+VWYww3^Sqa; z^txySaNU{RLXEzr32_%kzgoxE&504j;tYyhI&Iox;#ZaxZ&z1893#h?&1;Is?M;EU zEf~DJe9ofQp1@VVhB4GQ-ef`mDJen~-(`ok4KBW9`Wk{-tCid=(=ZC%aV!G|(Kf|e z4qM6ZKosVMcep4%u+q^&C@MU#1iy}n(CCpKpI_6NAjI|UvpsRIj={uF!jzCJT7kjG!T+n(P$Qh25vf;k@aS%=OoiA{zA39uQt9p$67S4n+B2KG;FtJnnLQl6x>_7FOMgZ*35_%UaX^%|YSm6=i9Qt-w5jlMy$ z;Z@~7e(n)cBuz+27rcS^$f<_puH4$_nI$4;S5040MZp_gFF!KII(O1`2U?B)>;-;b z6rC6a!H&jja%q#QSuItsiwNxJ*;EGpfg#u^5VT!*5kvR41j64)cw>IKfw^|5Xg4>@c81m{qMh^$19X`!pT_rboKwP z*v#4qo3wBe%s?b$+QROqc$iv$?sX@9W za2`%Ay;1aU?PbhJD@RHhqjv1G-Z5=Q-G48TBZkqo3D9C>MRN11-rDn0S71qfK}bcL zeVbVvsY}hk-plb)eEithC*5O*C1uFy=t1c`bBvSzrfxqEVap-sgjPxEjs4FaR)AH7 zqNDD>s$jaE10HVH`xX|b!-;-BR;0$z=LEXAPrp-bWd^tP&`6stnlWr4WZd;8M z4eW!BM_MI!u;)aW#LUjk`p$?#6Jce1Y3cjyxG0t8_o?}x>O-*F>;iaRPzl{@?baVe8|%ViN$@DtV= zs0_U0^YwIc$v){akB_Qro+kmyF-ZYXW@BaR^R;>7iv|t+tW6LzWd%SN!%6t4d|uI} zb6?<>Ym#u}P{U67fx{)ri|^aFhQ8YJ^mrip)0IKnDR2&aO2zggKHDJm%PAG#ZmO9^ z(uN;fmKvJg$Idc}NG0y}IVZPKGmo^qY@s{MNcr{UPiBdnVNv6Sc!L_ZJ`~?q89cQy z`3t?Beb5SuCY-N!nOfP(c$@6swU1qbCMhS;`Ot$u#s!vJvc|hGV6iNZJD&%DFX^9u z!$&!X$E$k{kACfMY_{_Y5F@Xdf3wDcu&2vNye>?RF>)fa^YSvPb=*IaJ}qZ`ZAWvQ zy};s1ndgkvwKGXHdf4*GUAS}S`@54*YLA>4kO-17I3V;@N==(8p593nmXl)-R#Z_r z`otmC$;l}|a@3fsAD!>Hw)6$XM~$4wh)*#3x@g zQ@7&h=N|1j_UzpwIM-Qz`S$JhNbSQdo)V%4m1Dj+Qglo@0fVrxO`UcacL}V?_%8Kmm|L{R-lYP^<)RjHK zJ$uVjSg)~PEg(scJRNFY|M1h+?yoMN-xS}z_-E+7(*54@b?Gic|6Gy_*#J_56!%Uz z#Fmy?TIIide|F+}iB=O85Iltz>(bik(Oq<~z`vSeC^lb z2o2)qbyQ}Fop4>q8ac}Q^&Ol10CK3qCz-qbJTKf6`n8}do)twV9?Rz^WG)=}hWkrm zo}ZDusxo_9A4?f1y$x=`B*|u@uZt+XU?4AmG<>Zwfs@# z^1|uypMa!t*|i6LYocxb<*l%W|Cq3<>dc!>x9NUBAy5I|uU1%IJqL9_5pMe+ee@B^ zW(B9Fr>qp5nErQ(E@uN8b8LKyUn?XxHG&j#Am4H=Kfjyv2{Q3E^KwbNSVhB)LSJ7u zH?y#0S$`g|*#-sU^wea>|9_M7n!if(hr)waw;KVOb>!~&p1&M?+^At57L@$u<=ewF zFbDvtwfi?f958>wtOGWF`?dCC(_rWoh^&7P@a#P6hG^P@qgo5mLzqHW1!e@Qncv^S zd(XNjg>d0&VPE$ZB%9WT#>R7GG(~5F{neJjoS!@>oIYpn{`S)Z; ztiCU%XofXB;}ngkHHhA1uC07v{{-bX;r!pj*gX5^&!Rxq3Q3F;WfoA4*8sA)2R=5T z`aMsM-@$uw29&~Sk&4_A@#?kFSGILEe~#wuC6fg-gH&JG0B?LDT6i8EUEKs!1zJ@- ztB8|lSKe6?uVFJ)1yb|G`~LmKyD_C`zch+#Zw<;nTy^aG%d1{2ZO*({5-)_pubyPO-$?u!>b8>Y+Tpk7 z1tcZ*_G>&IeAunp)m^5xIsskDPIdLjO{ax;DF8P3_7F{b;HJ%K8vG?{f&~5=g4&jt zb|r|&X=L^tb~+aAiP!J*3QvEr6BZYz|26`!;-L5m$^U9B%5l7DqB3llEi5j6?`N_7 z_SY+m3wwAJ{+Qisz5mCnuWPP*T}d78x+hOST2MejQOrSYt1&Hb2FV8C$e&pk zA7XiMm?}$5l;&5noLdz#e&NVdDu30>x8_-6Y-%~7l>!7EWcx3uc=|lPP=_1X5;ZMj zcKKp-_OLKp3^JW&kYNgf(-Z(%C1i&ol|~;rw~+w2+__plyD=at40_oDErYS4wmC+U zP+{Q>Q*1wg{v}yi^mUat8FPq?!iC&Lg@LzKLb`F5ubq6F+~J`wp_Eaq#oMxR@-K?pPlOyLqs+A3;>LFf{S^$qaz*Bk}T@xPQUq z(|d9Q|7ouk_#gIKp^|#Em{{%uzgfQ)p;4c|?tJ;jy^6#ZCv5L4gXjDF1S6jv@oWO2 z8^KV(B`1R*rBfo(H!d{Q)Xfo18~XOY2wm zd%kBND@*)Dq8if>3JowyLFg&4g)xZI(5`C@WXSkeQsmPK4aDtV6as0k5Uq!&jDw`Y zu>uY$o>-uP!sE3yaKl2oBjWsdK)-tY(salZ#Yv8o%2SgJn!8_Giss4D;fo zhs>uOd2p%oPt1>t`#hS89Ulax{27|xJBD`hu($H2rdMBks}|9I@_!2EK=ETi_0lS6 z)KKog)E01nq=v?Pecy~sZpkU}s>D_I)lt`Y8ad=h^IgHUhITu=^Zy+7UHzn5r=B(`s+ za0C$bhd3$@{Es4R2%?(D4Gr~(?YdBr)S1PT-M(Y5%o8| zVe|j_4QqHODKMdQ2(Gu*PvxIM(@ksZ0@u=c#ploj=J~|IHk=WByu6R$?9xLAQ?tV* zuGy&-0!F;@4h>LXWFCwSwx>`^?yNxALACyhhRJ@e7$btd@6*>f=#@`yTPS*W=qm>o zSFNY%*+<95K5BQIf`}c?RKcAaT6Ys=O=7z+1sn7?4%!*$su}_i$(CR60B8$N#Ay9O z&=Dq-lB-wBkF?!tK`?~5(wYt}zpt&xRwia}m^!D;i{a04(7kP&^{59E5+zQHh0@WN z0&|#O*^Cpt_!%s~K97uzd7p6WMFxOvv?yT4`}bzatSST87;yIn`y-s;dbppwiprHO zI@v*ATSXSQF8hnV;)j_C9}*Nyv~YUV>43AB8k+UBW$x*4F<8CnI2i#d# z0|ZXp<+Zr}mS`9i%%Hv#PivwA=RTCa0&U3=U2hC81`P#ejI+9lvu+4*LHp6=-#p;= zQmhL2&5{~{js)}8>3Xe&gp%3&tE7g&V90=J2!o*2v879i;^B)FuPgsxa%>gK881wg$^_%9X2{wxHt{4 zb$K+79~#!cs$qL=*8b=xfMG!fbm$h2EdDx@TMHN7nqZAq*}GQ%{^+UxhkK5UM=ZHm zXq1u?@}E%+e^47rN$4guzTWnQI&-0DLkQB)<@5L(wNv9SU4Y=?e*b)3HV80R|J2F% zXrjhCUKm#H&wa1r`99aVhvOCsRB(L}U2DrY)|qc3nryXtF|&Uj-@Is}*~j*Z=%odE zYd~uvK!c^dA8JkRSZv1|>~jsn3?J`f3c&*b^hfC*-<;Y>wvHDm5)znwB~sh_2@h;AV3g5^ z#QH?op!MeV0=0R|6FfbVIfqz#AV~WeqcI!B{yFh#snPEXeIoOb#|`_(W%L~4D4Lv}CM2tVQSCkJ|g|??YC6$Smsu%b44X#2vamV-ABi5KMoA!oX*YmG2KT* zE&FY>q%3s7ukXER!^ua91# zGiM@}M;49u(%E(&rhIA$a%PJ!8lI9~y=5njOhPKr`_;>g`7ZIPnR}DPjuY_t z=?-?jc4ZFf)WIiyx2IxWBAyVFKhSm@KDyTcuW)P{7mbpz{BJGG=StQgLa{i)Iq{ol zlMs<-9qt*Y(ZL34`g!1)$QjLkWUC7?6Q8{OiUw0xVnETX?uSbP{YSarcoB%nqHgKi zPjTEKydVCEXcgkjMxKBk&G@d!aXAom)Za;jI&n!v<{88)NHFJWJQ|;D(E?dh$qj^* z$p;shQ%zJiZ+6Fmb$`Y8E9PXmxgsd?NFG%M84&#HWWRk9ZfjTnwYFJ`%x)gbca#hU zd*L2^)xlRcc*9Xryo39ocrq5$XCvuY6pAfWQfL`>zGb0KptktZKU&vD%4srBeA?4v zV>0;AmJNC$nBcGHolrQ2C@VGOcNyd}ocOsVu+{cK-ivzg!c89qCQt<5Vbs=}CmGQ*c-}z?He=C_ zgH+~gCRE`(VF`QkY*&w^`Afyz%W8mD%e0ch^eA)3@rzYBEgV$1wt?2TP@R_B4=b)}NpYvvm}+{H zH*y;&mtP<&$T3QP*}ZSyK2-U7;}`@Jo-u>Q5XemItD>C+w`yg|sSn@Fr7<%xz2@q7 zyQbpxvIb{#?L-GU%_Fg|u+Wbf8;@Zk0-FD0`@)x=+D;bv0a!cC+|~jGL=83(8ELgO z5{w3yv1&rC64UeWR>qJYbcu*@wGVUcV=ddWk?z};KvDM#>xbr84;(mfB6#EVm!aHC zw=SsEKovUMxaG1IAFnRrMFa&u^v2ngdrV;r5`t-sqsqPi=7-c=o*OpzYETI9l=PG zP*!cVe)6+fr5CNYN5k*-U^Z+3C>736Q(Es#1vP=`2K{0Nrg5%5miY>tw>g0Oo74|4 zAa-GAxwX6WzzO7Kdc(nD=e1S8O{FKBB#9WiUpJO9^&m`?9)$X#Cm|_op$2<4@8xV1 zP>-7qMn4h!iBr6#w^s{@^+I!FqYeY+9)Zhs_1d*)Tk3_Cec@q<3rczD4djpf_#udf zNH(fAg3zd6k(kK)06csgk129?D>@jpGc|zq|BMI=E4VfM{;_G<1YR@xwUZI-_q@3! zh?ZO;HIC$XZ`0sY)%=J01KfOkGGxo=XGm}_Lm7|3C)-0Jufe1-Wsr&qJbE^adzjkR zo<$7M3Ysx~=Ziiz#?Cqis^WYAO*cBg#R*iko7;IN5fc2j415P0&58W;!L9cw1Ciq9 z$1?wf;<=Y%Z_g^AI@ZRw=bvkcMDtPB{)WYyfFbnpkyNFTDCfOZc9t4=#XUBdm%h}J z#Td^F+LE(U-dpMu*hggo)Uv-n)X}2(CuVO}Rx^ovuX*rLyYw^aA+*2I%?Mk(-E=YS zZwexSWD9 zk+dQ#xrfzI%)mAWCxrK?47y$f3v__#uf~~D9hFGx+FI6Fku=2hInWE?UFzqbiS)m_?4ib`OL+`QLCL=%> z*kfq8BUK$aQjVG;qEtpMt#<#qhiFzq!e-Vlm40!9`uSpFsBeHTxm=3rX#aed8q6F! z6@?DLv$a|&!tB6dqOAWmf(QDGkMsVDy@=Q;yrw3j(-)?5V$rt3c0iQ6DquRjkL?_3 zWdYZU@H76OnAwU_&WnBPBlxfKde4LFF(Ajz(@{-=PbwO71i}N3xHVxz70$-1O3_Rb zC)G0Z5p-t)q;%?Vfk9|hq1nKE0jUahl>cjM~$IpsXbCPRA>f~eR%hRfrap*0Jnh?#%ZZMZ2Va2S60=0LvCqeMp%UTF3imi4>-$7 z_t5n$3ltGg{JQh(#YMgpBTlxGK}yEHts{Pfc7({c=9bY@Tw9clcI|q6tdAk2VaE>8 zE~1@bYD1h=(?V)K^s;UAG7aAf7(Ce0${b&;Q(b#|(|)anxLd`R?J)j6b7mPNJKKv3 z3$=S1*WJ{qH;s?b32)daa?qh9IzWS?qa|-*vA5@OgC`7*^$CEOq)%0 z*v*2zGW1k4NAIR32`BE4YCYE~OLuOa%g#L)Ja@A_cR09<-dgU#g->@2L^~)NsawCV zx>I-UZhqUiH}&f1pk3#K0hPefwR2;CMk+eIQVbt#`DpfiXz2R09nNH(?YlNpw)vLt zHJ5d8bPU%K$$ppCq7=K<9`nesH(s3*pJ}1DIA~Ipbd*4(FdqtU`!I)z9opsKOkfpb^Ij)TJ26u8$@Hg7ZQ1%IzBCd9|Y!u?-lb_tdvYO_is?rQi zDsC7-a02~c`OTbLQ<$aZi+ptQy z_DGebO>`0jm$UN`E7Ss~@*hZWxTCK6CVkyFjW-B1Q?lFQ*e5#i3&n--1C^8ITlSFqDpAOu?wPTNlC3!j%hlh9BraaPm(5R z#idcJWTQ4)i;m)~(UXwnxWt(x>e4DE2eqxHTE*Tt>mS?iukWuf`CY#Ed*0`Jp7#ZU zv+TvkwP2TKFg*7ZRiykTynpXi>5RRYGzgK(-p=*whp%L~LPI9F|PA{&xGl zLD<5N@F3XqEW8rvqdlnn@U$^k&4IGXXCBLuSEVRu#7@WC{|h$SKEPHn5OCEXan zi_b?1dDQPl0&q&m{aMRLtl*o7nN~@p3+h-iCnl6J<_iS<0enVc;u~^wBgAGf!F>ZBen7#uNL0-I!WoqEq6s%5Y z>DPZeExG28vk7NB5~wc#-VjsYcg?ZlBV5!Gm$GO%kRyN%F);HEr72hDTOZ1@!noBy zJCLqi$i(HnHQLHuaENpH@;A*UAIv1yLAo?QACg}LdLTq^O9BW#p~rG=>SI5Z+f1-~ zG~YP#;U|7d4g)qY@XFhtu7*PxXhg3Ymy{27gEacflYDQHXKk7=3vsZ$?G!YJ_r$dh@U zwu0-|L6f1_k9c?MF(@`=o71T1_5TZYBq*=rGLpv+B#{#0;>`2=Wk*v%MpDvf_b=3cQA?UIOP-tgt3eUXW8uBL;FJYf0u?c^M>$BaW$x@=U0Jz(@8((u zzj4Jqx?nm;)77tF3MV&5~Q!wUrK)KhvHX#UA(kJIVg zxy2m>TvXH~Bpo>79P>aNMkWkulJ8B1k98KTbSe49) zf7o%@e{^gt(NH?HbU$4f*{84xR<1NOH*4~vtF#xWP^vzqr_jj9Urg2(Jp@ghN7b@31a2yR~5nXN-y6Fpl#KQD5 gob7$+-Eh-9H*@I4*e{nlcfb{SEIRCm&{LQG0WZR#e*gdg literal 0 HcmV?d00001 From fbe60ca93339551ce3d4af7dc017410bd24c0f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=8E=B9?= <1765557195@qq.com> Date: Thu, 9 Oct 2025 23:00:18 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=AC=AC=E5=9B=9B?= =?UTF-8?q?=E5=91=A8=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ~$第四周任务.docx | Bin 0 -> 162 bytes 第四周任务.docx | Bin 0 -> 43514 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ~$第四周任务.docx create mode 100644 第四周任务.docx diff --git a/~$第四周任务.docx b/~$第四周任务.docx new file mode 100644 index 0000000000000000000000000000000000000000..715cb0ccb9656337fae088c47fd7a04b7d843516 GIT binary patch literal 162 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

    `>h_u>9S7TKGRhzYezD5WiT^;UJOIRA!g02WIB zfNMDXVJ#G}FUG<83c-~uDHF@`J51okrWK0cp z+=US_oPG@g^~Xr;|1@DyY++$hl-JFnz}wS-gw!n7``aG{^yG{gWGZ;2KZ%( z0H!!YGu4n?D>(Zpfcl`I0~8MLKL8#L!EIAYBttOX=Y@|0AQ1X{hQ~zkaU+-$hNH+T z`X2&z5xXXEQR09uMfU~TA8I53MT#a@QC6PP5exp^wF_cyelnqDJ>3tN0XTNxrNJZh$tLr=Ct^zWKD8DaJC*F61_roo>wf7Uh zI4#|Jhn_#|%6LMr)9*&TGnt*917>blN4-qP){_R>u4Y!;03jJpB2*T1bvo1H-SRKV)jxaxRVFO{ zDsi@dD_SsF1R^4$vW5m2#@4w2)?m^9u07!A8^MbuKQ|zIm=7C~fZN!g8NGjHlK78= zEO0gdYHj!*U%da&9r1tg6aP2k&3}Ji^nltJR@XKIoC=M3=YLrS^*5b^$AO5z-No|E z7u&3GVgd7isdMN z@(Yu_2NaKCUq&M8_}QrvLUgH<_>aq+A!~ey& zlS9J(8irIkMJxM$nTC0q0!o+iU-(rWHDebaFxLd5?G*$sp#_D7e-nARcH9=WT+ubq zFpYLHbZMs$R2VEca{XDa_nY+Mzg=a(4h-m8Z2br%sY!nCx;enNKlUpex}H6?SgpPG zbM6z$aY@6U{U3iT#DFdd^ddf}@Q_vU3&AhD%ir8q3wV+Mdq_f{HD}b<4HnM=94Nmw zZd*0#hWvwE4Ny}2=1wV#wfARhO7rkFPL&s>dM&ywm;Kf|R{FYTR#p?33jBb|`C(tf z-|hRG(JMeZ_pWKdp3DDL3)lZADk7D!!RXB{cQnvV1GspdbZqX6mC|4=;xyN>`ns|=V9GShV>Oah`? z=LOeX01-m~XtB<_l2umR^#F?m=lQ>O3H~glgFQdM_CHn2toh`L3kJ`GS*2_%4pKQ8 zIlXDoF0QEX*VL{PBZ>zH0S(m=tP1F>KzF>e@yF3=Qs)xDOq@IIa$+da=Fc*kZ@ud& zC(nmDJ$YrTGU^t4?yoAY>hc!rpryxQjSppK;4qXad@H(Ns;60|=`6oRxsHW{6Q+UH z1|}MB>C6kT$AWlUT3*w6+i8;JmuzGJL&pA%jTY`p6>_P`64iDTk~~obBp85t5lI3NCnPw2mb2UvTFA(NrnP7l&nQ1| zgA|6c;Dxi9*D=~kx7#)_*`C~eF&}|QM&W!IKT)_fZ=oXxO9pNiR{hxc<3P5XdgQj)%>ty)^xJfL*yaKMj(!J0f? zf=P_yNH_4TY0SvGM|qvsVM#yt70!h+ z=9n8)Za2c8;uLb;AGYpzM&U4{Lpp8Q71$rvK*5W+8X-CzUVhr>gl{YRvupi znMc!%eJ4Nw2N&}ksL}Q1p9)PC{=nU4*DcW1D!lpx-7p|>haA<_08Tqm(677O%9hUZ z=*shze)z;@Dmt1vgwtAuj!a>aNCiJ!a+Bhz_<)OkBi@koI!cf`BiU*pfAkUuaP(B3 zv=L2hQO^}y{C?|r+cK2_M1~Y&gyw-ccA!C~=7HJp5ULeB);=Z|8+YYxmmgie8h50% z-L$>!=WsGL0rdX5kyjCUue@tPbi|TH9BTWUpzY#Kx}GRsM_w$j+8buuy5p?_9HQR! zVTIo0ae<+Ns|;wZ6U5QQFFd7EK^kj_z$?b%mTG3qqZpQ_4XlY~hExbleDk7L>`!u& z05Dj%J)-pOx707VJ(>1kSJ?rr7h!1dB38yW-kjkVkcFk0q7edt% z0dhC@t4#TL3Lz^g+o;%BD8)iE49`_LHl9z+9%#U zV1XIHvew2ImcM%i|Ag6hqu>HHO2#m+EV}Kc_F<)N46(gp0%f6Qq!b65f;;3=HV3P> z!y8~rG$z&M!Z%UA1>Qv}=Zs++Qv{JaVlHlxgSfWiSepm zX(&hJExQBLXsVzxk=^buAMoLPdV_zRcY)Vj@)>t#umrPQIek$Xxft12e+7ZcdN8UK zXgNQ!rc}t6K!-APwJL`23Jx~ogg1sTPj`%Y(Up z=|X0}M1|Eo{x5n4diUGj=V!@GZTW4lRE64DJwtx|uYw zZ&kAZBOZ|cd(XWfw{YT#_oi1W&K~z;*haIDud9Cc&SES2&BzsQja=(Ol&7!$K!z!G zh6r~j%SlQ`1595bSy`!hUr`!>ug*(`IM75f23fppK_~2FTQ@(X=TCaaJV#+Xb-J70 zG5_S;ToF~8%WDEoiy=nD-Co9-90#|Gm0FnviwzS%$X4NL;s znDqObb@3<-K<_)xp^(bLFxex?iqgF+s71PNa^My6R7TvKdDm(25Rt5B1Hj)+8g0i? zT(f&V;F9YqMg0n(3nib#E)VQHr5c#!r??_-QkYEAXH6ql0w(|1EYjHrZ#N`_Sfly? z85P)hwfK)-P1s+pUjR#arcRE^1U<%VpvF`LkYqZ510pNeq?eMInDqpArv~>HhOitB zJ|26an+MtBE&`}CneFkTwK7B?5UA5ZQbpFHUi{nSYr$%;O)v7Y;7t z1FXwxuPhuAAAt4UE_6|XFlC0zOPgcWYWc=<!MR_46cP#~yE z!L?=XGQ20lmzG!Uw`QHEM6`);s2{IsRhm>^u11=PPIQr6aCrT(kYopR9$k$jjkLI! z4fw7`K_la-!ymwXN%Y{`P1|MZ1@5aCb)s~$J8b!&o=@M_Ar}~p8pf(DK;c_zuSe*g&}zq0m-=zl z=0VD205*M_cop#f4a{bDq%;!0^ydW_{&rqpDeKD;EvQMg9iAQUZXJ9leUdsf<`A`1UU zdy5i(HGVHL4UtI$ckX{fdvHe@L2^Pq2pkv*FLSE=>s>~u4nQ~t94XZY?`l^)O^ z`^}E-@gsKDDJB}|6`3FJv2m*J^v8ZfhC-#~f{v`Hs|XHi;}-cmsp9S=Wg;X=vN!m= z@s~l;NG0YIJ*ET|rH}OR6OSA_iTvzb4S3+-yu@Jl9@CuIZ2a>;&nt};A?9q4@~>?7W9((@s|p6ZfOCDz4r?~&%Btk$T&>wv zve%q3I}Nvso%D!Ho*3(`0%O$XH$V=+_TSNJ{kK;GNXn}7gmHI(n%4{n<6QMydl@;y zAHTM@uS|3K`ILi`b8Ff(y}IETw6m|tXm4xvEx>hh{?B$Lzu7zh)*F9>X*Cl82Nmr9 zvLG5ZG5`k8nvVrY?bFGX2!9eK`IpTlcdcdB& zHbUSm0fsmi|8>mxxvNWD;CiRh$yxW~txoSd#sQRR=KcCV4_JR&9t0No`eg~mgz5ix zqg|i`01G2PCQGUtd|X!n^O#&_#s~l2nCri3Hvu~b!K*xCuM2|)yoC6@#$)-WgSKZ* z_Wy%}zP)a_zdpRT4pr39NDO6J_CD1v(-)bURvMJK*GryHXDIR1e_gUsQy3CV z2#v+!Dks9^p>ZWF7H=>b+zU$7n0@u=^^r1?|7*>oA>mCK5@~S8`+&30_t}i7;43m- zw!+?UcJrN?r!-TX3#p0wDLnRj4eqBiiXV#MCGlR_wlnI|OyPujvI^S{mF@31*>lVq z5_Z7*NFfuPy#Va2uewQe5Fq>?(5oJK_Du-4qw4;so841qg?pEax{J!mTz7}E3tW3jDi2wA zyT^Ixv^)AO)JztA{IbRHJ_I#WR>G*xKhSF#kYC_FLuttH+PS$JzX^SEj9rCSUviZ= zB=-dInnFy%?=E!6Ry%hj+yz0}I+enscDvs(;X!uo9>#*@xRzyV%fsy2SPGBoAqzeglu}_* z@xwce`X$xx3nx`<-##s&kTve{&YOcDre_`D?MrVOHGiLcRVHDk1{Y)dK%%^}n~eKW z^Vg=U!%DT5J1fh~mn(L-Wr!jsJgG<1BQbMBhJs>b3uVrMw)&_F`GsHd#^@ZT`hb?h^eV>EP6He+^c=lXXx=(c`ATU20 zBRYTY)wfEA25Mi~;W1?Vi4a&VVq-UP_xZ%av{fO+j7K0BrtKyO^^f-rbH`&D+F7-Tlzvbq7`ptG} zdW+}r3SD$$h81-C<&T%FJwpNYm$e=8aLMYK%_c2%^IV@!PRgbBQlFdI^|G*SO~bQ{ zYIETQfAClRVCtdD)Pl$ODC!_0PLf#M8ei$Y=*IbtPX&8FxBg4SkruhM)Sb;VqLGdb z(&Qkp(@v|8u)Ta8Sya`updH0$#3-DxrY%P7RNqYp2G)^>CIi>v)Gijn(K}q?!fc~G zz46@29hWewPxrLSlZ&)t={fQeQi~;MNGO@(!>cM;hojSDHKw$5{@b6Y zXbR-~Ekom?)LvR4(R+5&bK0C-xTAALp{KoZl$f3I402tygYzR*A{hI^KRCqC*7wZ# zUq9Zc_}ue6I6xdLHQG8YvHILAIY9+)9o|X@`RhGov_e`W7p$^2AM6&)=Bbk9B1X43 zi;UhSAlPLSo!=brbRXZL6N*orISt8Fq_(1(1%L5*=xD9jCM3qcnKrb&G66k@6HI6NQt3Jzc<4|AN^S8?E?3JEZlX;^dI=tU zC2GQ^6I3A*wB>Nb@H#JACkV^Y4~wJ6D;sNzwftk=G|s2}8Xc-wN$%7Qmd7LVG`C~* z`x7JnBX}{|@fFR_WJ+yniwFWMW zPh(qnFq==kIg};0%8Fd-HhzG>9YjzwI0}E4+sB$2TKnLcQi7)RAPFgIzP}>5hX4eT zaPS>nT)|N&NuJGVTVO7aV-G$aYT(d1oyppp@;FwOk~B>E$K>d*&)Zr*k9R+9Livz6 zXRb(V%RkyCGEvXj$cC0y}?+wwF5XA04pyUf{mw%Umj$WM((> zGD)%NJ}GTbm0VsCg+0FMn|awrb%n6(wKRw36}#M(d)x7Brl}mWsq|YH^0XICn-ZPu zn0eD+C!U|GuNB*y^=y*E)$E$IKd(92$xqX)m|In*KmcrH$~MH`sqjRY+CNZnSnho9 z~vAr%&VowSE?jGLMTQhE_CXwv?R^eyt2oN#E((-&+z^zPAP`>o`F!a=`f`ZjT4HT zwLU`BKzoCQCU1H(h@U@sirmbCSm}Hl{VJZpw$$~k=Nw**7Kk*C^gCW!m9u)yqTbzQ zcf+o_VYaYbjgN1SZKV869ccB-Y%DnZ899?nFrE(`BNB8;si*+~15IUG%2n}|SlkDU z>g}s0-LVqz1ytuLX9*22f)ql$M|M?DLa8cw=V?Uc^U~?bq&`;#%hBQ<>_K^sbY zkaV|dV=T(oxkw8y#~?Y8)P;%drk`K57%Q4OA#s!t10ronVSc8f*G)|N z`&U5$NPSId8bofyX%b69WI>=C7vk=+wGH1@Qna3d<=``Z=+h$Hrv5~D-y+_SwtYUK zlL$_srKrU3N5>m;M2^)AAZiJ_^vF0{u|Xqb)EAb%ifMv`c0Z4OarT}%i`fSr)oD>x z%)G8OrukGRkR`wQifFM257$hpl}K_I$Jn&jCHKCKVwGNFMdvb-j+n8itC}1f>+s3y!lu?ASE>?pyOpAx*W4>2Q z71eml5>KcGf_!a3QANUUue_Mpy_^&jExPG~Ui!WCLJ!ni3S&GEH$A_T+PMg~Wa&-w zyy>u~cVw3ca5CA9{cy3A5Mo_>c7-lR-}&@I=+900R{gvO_Y6P8$hxG;%joEMpAXzZk33=?hAVy=!BDi|eK>T>ww#Rtt&;!Z+wA;H{MR%zm zh2?+X|3Me$`9bNqepT>^6Pnj5oQd1|;E>FoGetOyFLfLI+PQ_v9(@k9k!~&Tm;o4~l~;cV${2df&?SGmwiL(P)wdW$QqVUlw9{I*{* z14}ANiK-d6dY_@^1x+G@Xjze`%2_BQS}yRVduH81LWH92ol?eo3KCS)H?BkJ6Z7XU zo;J1G;HQhWd3m!4`HOnJK;DYt5!V$Qv{{L`s#N+mMj%?bNn^Z#hS=KUxmHesaO%J< z{_{CyRIrva$)#bDUUmKLbS&edssV#Zo;s4Rrt{VO>^Q#6Au~na4;kck0+Lr!)eic( zMh`SzN*hU%A7^)C%feOWI7=20a59zY;u;-dz>TgMZFRVL867?lw*?Ou3uiO*tjB#2 z5n@QuR_*Q3U~w@g6lR_jvi=aPh?%sjF7h#X!YL%_bC|}uR%SE-Fgryq5`Ct$kmy-Z z81hk64YB#nJMc4$x-&}40Ls`M$0%!BeI6OgBsf*uVr0juJHn;= z#<$`)+!{mQUQ<0I&{#2!j9VQ7AyDi*FrR0r_UNQp)k@Lfx?qb$@!d?|qR&&s%WIJ~vsN7HBC&+oM2i?8Evj{bS2{57!pa|SR8)?*0=2h_{ISIQ2q7Qd~t zJ(t>RHTMlW;QYZ6s%UAH|6Fn5JEN8NjH<>R6&zq5UA5@(E&S*r)Seos#^a}J2pIaz z$*sd zt+figA#K+xV$F|2KvsjW$CX20Jp(b;ceo;v?NtZO=+i_9RV89gfUi*w1f%gy4v*Ei zc$mJ?W0U{*F8P8Eq<>jDBysnaWHXhQv7yr=A@|5{qZ-$6gOXn`%f3Ro5Ok-hjlHIJ zoP1?Fa9j{-l^)G%vZGn0rkup0c;9KOTM>B?5LLm;hzIt*93hNeWHN58j!mdbCM)@Y*gcQE3lb_M~qG9j(r# zB}iS*SbB-V(gfHZ=dv5&(o2~w&?Ydczg}cAyDNeAv>%oZ#76eLPbjrJbUojE4`N}6 zj(27OOl}lBk};=0Ka*ZrA=>@sQ=u|m!(Zm69I-j9JHm($MhmNo5a$&p6A&XK%8ZOz z_m!kq=rGP~d(Qo%WGux-!Cd|e83)x|L=xtnc>mM$%(V}EiuP@u>W42{{i87UM5LZN zXFxw(D}dVOsc3#IM90{yOG$s(C#RTmv|c$%7BBq}d`z3bx!(BQRV?e{g8!%_qdM(o z>yI7|KOAbRV4vaR0F7>6FpFYKV1x8t6PaMd+K!1zkTy4#djl{evUszI?EpKz?K*DS;R!lhX3~T#fZK0WD;1~(4v>5Z5 z)G-10n|wy4+Jc7<`t7CZ(vq5^tt*bYCOa)B-|>*RSv#Rubr_rGo192oh@|e+v#zv* z6~X#0bzgjp2~I513GQ@EXq#{SxBJKX> z9NP=!^8g8IHQ|L4TE|qmU33+8Vn&bPy`{Ez)9f5|VyHK|e2w2Tp=ngqZDR!`P#p5I zxK@0iV?77jwMTm;W&1J>(^?@`DLmw*CfbB>730b#ZLdrpn<{??rYir=u~=2;Pk*YJ zr1L^w3Nu6M7jYO!0Th0|2H*_+yoVnaWvpAhKYAcLO``5IgzJ6=lECl3Sv z$+nhx^*H3xNYN-Q8_7OI$EPBN)cXxxa;t^DTL?6i1=~J`5ZKaFy5D}IoX%B(wi6u|?SVE@bN3p5Y$a}>2_EP)sVkn=y?}$Ko++QlO63hos6!e z8~Tufz#q>N_c8~4hAaoRuOy02 zfb`ia%0WxYkZu+zV_Z8M=+-r|9LD6Fwo7$zQPM;plBw&P6@XiU~0*dza!?A1sI|dVd1WS@o|mv zqF|l!;`;`r&xwQKQd_;EzW;ol0cf@znfCPH{T8KgcFj{iXbp3Fc8#JR@M?$FP>JV_ zaXtXP?wOW*L0;{T$5KaBzaaq7V0%CG5B!| zr_w0BactUe|rm57_e%43H%Q#9V@fQSA*>x2kc!O{kJz>8xbeN0GWT5 z{P!PR`ESL;vng{_pZ|pn3hG?fPL39!rO8sY15l-|Ss<#spbvQX>*^T11h;c}CS3zxB$8KKpUsuA-VlM7tayBW3 zvoA+<*t3tNy&D7+y}8dft`of;hq5)lJ#N8d-s2R%pRq=~JySYfdS6)RJmFC7R`seX zetvf=v^6kpN0VXmh9`PY^wpB}D&c3OF&(D0ptVn~WiLC3=M9?dYwSVYn(+3sMZvrG zgRe>8Q72qfklgdYy(4CWTZsybcgLfP_g9;NLLOJ6Bto9|Mkl2$x0ksj_Z7_%Tb&j2 zQfqZ6`|?+^0zYlKnjP=f1SXr)n3Ji_H?7!Pr!NOYZV!SIp`G+OI4=$>8L7AsH3uk| zI-N}27abf5L-E(;BHQPK%~J>m1Ju@xUHivlH77qBYz^C%a4c7xD!FUgWQ@cI))6~J$GiF*fbJq*!<7|jlo#s-f8jdmM?3Y3e$oiDS*fY64 zYb?jQo`^2{`F&JMYvladC3qB@Xh-Pl^+9g0uc7v5S1J7cSzk~$!BC%EIRd7jsu{s}INdQ`}r;`*($QgMg22w9vsL!I3Ro^_&OCeEOX~VoZu2`vvrs zlZho&*7JZuQ|__Z9(J$|oYgGzbN_P$x5w|V)nknLO3-;EQ(jQN zHCBWQ*RqRAiHd?=Znlt}FgFQv3CNd3l2X)}r(~+eR~y)$1RO_t5bEgci(y+Na%%Tr ziIIgqq|E>Rg&uUWYU{}I=6$)S2^18Sz3~;fUboTPxjK1WS`$;aiQQgANm)~CuzhGK z>Zzf4feA)b-H5Nc%a|B-kk`x@u5xgadh;4~Z6I@(%SX*n!NAO;6eXwJ4RL0$r)Qo9 zf+&St4`g)MX?@5^+O%3V1`pm8N2ML}LoXR6e!9=2Tur>#S#-jj`A7*7*AJfL1$sU` z%)%ZI6F@a2T?y5p&uOm-(@>UWBM8$@x$kQdiC@klzwVH#MdSK%MBHo4Nf-E|o)1Zf zp&Uw{bCa5&)*iG>Tn;Xi9?lhvMq#tGdqn)9;f=^T$+LWR4K-ok66B2XhiFdsHbPbh zq_ghx(<6wks}F4~hnwqKtr&yhhK|pz2Zg-cQkBmhuuED#O}Pv2`AJ8G;m@dnnU5S& zPwo^Z*!hBrxn|Mi6+W0IJI6Zh`6_8-_oH;P8Ct1a{T-|=o&)B9^!2xcJOl4J+PhLPqlxSE zDP8m%mMSrpzRd=7=u7%im3@8m^HIbiJ5*z{nsmlKklSt_xlZqtP{Y@bCwZ>f>5=zE z2${ZSJI`Wdj-{_cBlRxH&PDol7E0gGfBLjfVS1o@08jfWP~gzvo;)zNHhODkZDY@5 zWNr7Wti8;9^nf}8?w1||D2)G~-BO}N#kI ztH}vAnzkC%^>u$~`@rf^?N_O!n2eGs*R^|Bd~ZHH>&mfNAI?|tWLRepSKb@*;M%dg zMym`aAstkw<&m?0N>&B$*R^s&Za`~N7r>WFH>B!wNGO$*kdLmZS!fuFqV-x_Zjc9x zxn4Jr=a{XlFE;&=5$@b?iO^J^CO7UU#ztXW(3#|bCRB5~>Y+^lsXsE5gL}vSVyQZV z&E6pcZ`3J5pYfCr-b<#Xi{%4l&v}852S*O za`zP1A6|@ydo+2vE$)+GZ$v29b6AL8l1R4LRlTb~tJQt>W&L&V_7j3tTN_Wd<~?HZ|r?0XlUXIHYqAUEyvgC3a(&(Bdr>d-Nj1E z=e}PeNB4@H`Po>s_uP~kje=&TRb2TCzdtN?ke+o?5gg}|=&cBnQl|*5{6c&FqF2Vt z1ul7sKLE;tBWkc*umd{64HcUwbpII&1M_(@AyO9$eKO5Z zJOU&aTM;oqy|jk}((2Byo+MI>2nwacC!g4?HVuQwzsD^?@U$J|Xo-aoa9v5JPM&-U zX82y4F`B0KHHTpioE$rZ@p(_C(-Terz7>Yi2nT5G1$*%H(gQ^}$01pzHJpw$Xa<7#UVxH34)3^Dp(M)*GN@ ze`n>Or|fF;&Rz#rfZxje{SOdF;@9p23FUzT4@6o2w3P#WG(Ed_7WPbxu=jsVSOtot za|UR>V9DPm%l?)UhLQZ5Is@u^M@u04f0l0rkNX8FaNtdk;NS@VmKONW890w$$$!iI z&p+}{59IoyUU(KbdK2JaU|pKOZ8O-v|B{KdwS$$l!*3Dee>@Sc#Co?GAiX}29yaUu zw`~>R;(r~{C)?~K6)Okhg`(|0V4 z|JMrg($QUjzV-%T#+nwW5$G#%(2YQ!xp2U;qFB literal 0 HcmV?d00001 From c07d263049f54151a31dbe684b615340a978f494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=8E=B9?= <1765557195@qq.com> Date: Thu, 9 Oct 2025 23:18:52 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=AC=AC=E5=9B=9B?= =?UTF-8?q?=E5=91=A8=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ~$周任务模版和部分编写完善.docx | Bin 0 -> 162 bytes ...周任务模版和部分编写完善.docx | Bin 0 -> 444616 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ~$周任务模版和部分编写完善.docx create mode 100644 第四周任务模版和部分编写完善.docx diff --git a/~$周任务模版和部分编写完善.docx b/~$周任务模版和部分编写完善.docx new file mode 100644 index 0000000000000000000000000000000000000000..f7b4981f9998461612d0823160e148437d0f1757 GIT binary patch literal 162 zcmZScNzKbI%V!`Burc^Bq%!0&MV_NS h>KPaqa~#0xVYW6*+Xv=HY*zuxJBUJL6u6JB1_1qqAkF{) literal 0 HcmV?d00001 diff --git a/第四周任务模版和部分编写完善.docx b/第四周任务模版和部分编写完善.docx new file mode 100644 index 0000000000000000000000000000000000000000..ff48886ae9662905df65dbe31583bb6d3842bffe GIT binary patch literal 444616 zcmeFY1D7Swv#8y+ZBE;qwrzXbwmEIvwx_M#wr$&XPn)-Y|ATwpbKY-oZthjPR@EwG zM#d8vl^LNR4GM+^1OWsE1O!A3q~;uh4{tf%5(Z{qZe z-rdHUr~nLvG7kvk`}+S^{ufICkUTEe&xj=YB=IhMKxes8F95}M88D1Ot;pBYNKq#G z9>?qb!JAkTjbw?NH%YF<>~zgbAf34DZZl>KO>Ak#!Y=Vf3rv$e*EF&+d|&J~oeA33stnNV9#(+O6j-#_~xd= z6{%krnhc2xpG$-piIRBC=3On>L8o!2@uaGVJzp}XzWpL7>c{*U2X!q?2d^FKy+w&OsU~(d?@Yp?I5?C(vSWBp| zX5+U#ieZs9v&ouD)Qs!2Z&E+~1RMwz1LB-UvyjL}5)y;F!dufYC<$~M&n5xM#iL)%Q zV^X?dkC$r+KS$|%zg;I*m9|;eu$AOk?Gzz|xDUo4QS@?SEcu>ddzWXPzKtNw# zpg;=$AB@vgeZW7zb#wQdQrK^d^&CyCofzo<`Tu|T{x4?szcjrvK~@@+2`S_{;EQ;o zlY5<-WNuSeN@zYd**Py(rjL3Ep{m&87Gg_0~y5Qf=W$tmg7#{x)OxKV} zl7S6Elacv9A%??B{*YmV_Q#$D~XY0G{KBl5oPz zpM>xkHFsH)51cml^x@54mB%c9tAY|^HM>Fo|8Pk@u{n*S0s>Ow0|7$*mXVvCqcMZA zoso;p_t5vxn0MiAC67DWbn-;A`Q=A~f4YT;`nqWYFpIfxeY$8JyFisax^U`>j$+!u z?>5flnVOB43Gn#gHyS7oBI)=23m{I!T;VBtp=$WGc`5$_+gx5@Gtn=Diz|=2EP=YV z_+2WN+SRHaQhhto5nMK)22gv=56-3UP0p0WiS}Y2!AQOJ^j@C`7i)^7@xzN4=JsJl zN&RaWHW7Z%f1LmPdh`7_G*y>h;739bNx-)clPEYho%nhv{xoJ@T3k)Pd4lZg8aT9{ zA&ez2=o}sYG;d*9TgSbJ3;+OXK( zH2WMhAw`zWkE3Uay;U*8*w`Q0Hbq7!XnZj{vl>Joc8_BF26`x;QBN)*-nZwVbu~LZ zOnS^K_;BEf&AVwy3OGZUQ9AtnQ9H_q$bHuGlcZtUyXNvl1CL2!;Xd9LLPg>7h>SjA?%t;a{InnF>_&ys}OcgzJh!|qUBOYEPs zi_?RMAqYF3W%9~^=xq{Tk|6YB;EA3=*@Hzb;6`x@=Y0h>&9m}k>#3sy)xo1td4Onb z5+Mn)Wd?zGLD}GYYl}Vd_)l&l>QHz`b3WHXXsQ$`JeN}MAKp+*3VKN&*Nnl6ky|5> znF4|fKAHK2jUX&Rar6joTw4s`jl3U_&zf&f1TORe`rd`!ZawvOB!^`ob+iFB#zNt* zX_G z9br*v9mPF)fDcMILHL~hEq!5$_t8oKHSh@mc~1M$f)WLWa#Z8{ybJa7Hxk`P+%n`| z>crBC05e#-PAf9?X7Nol2LWTX80jcj$FcNtpnaX-qmRK8a)wM#sze*Apq`0#H+KTZ z!YE?u!LU9@+{v@{j_EMsY%PP~BdpjCWRh49!$s2(UTl(SpTo179r!Rw zJx2{EWXwoI&4Kww8*p212*{1AV%iFn{5QjlG>S&eQR%0^;LLLlFatJbx_O?urU`FX zV#Ht2sBKM-!z29+#orhqwf|D>>&cLhLSm&AksJ4qU10U z&zGdZIh%Vt%>g+gU0cIZI4e6U8xhFBp1%l@52^iWCc-uU@AxkB&_IgMX!b^gJ5EZz z-T~#fU-b0eK|*MbqBah&W9mi^W{mG$ak%scdgx78m}U)wCIi20W^(iXBou{3r_=;} zW<(I&n^2H4V95nuH0Au7D-DUCkmqH46wl%@m_W+n5gvgCG?LxCf2L+DQcVB#I#_kS z1M9ws`e0!*uS5uZ;SKG-yYB6g4Gl!$!3#An<6U>-p!9_cG9uPv-m$koJ2#q93Xo!} z53Zkn7?rK9i)I6|F%|J`2tx~)_4tD=fCq8zv@?a%G2><$)d^`&)zfbAVS-=*&9WZc z>HVy4Koh&ln1(aAeYh*HtcV3p;|4gT7|Pb0-H+8XC%n5^GzW>BOk?Pyea|i94kZdH zBF?xlNDe3!5iKS=L{X&D(kRx?s#1zV$b9C8W_OL6T~?@ItoM4g#W?F3Ove60KpNnF zPotsdkBJn#3qD|eb4SIjJYjYlxMm3Pf>Gan61xnTogUi!Rr^(v=9wRT=|4N!w*;1k zBc3h3og@i7t85A*6Q!Rq<0E%Un1a0jmd2zeuGoC4=`-6f@t0?Q?W+Hs?O5((#RgI4jeF(+lUy=QXjLc|`UJJwFkVj2T5jNH!byUJM`dt^B91R=!1W;Y{kUg-hTi zPhqk!`%KxbnU&OZXA>#xKff)eORb5>3Sl~=?-HW@Q%oOXwo%NH^|m{cnraPhJ)HvK z>)jb&k(87TXhJ(b-D!Y4z-5^VZH)7(0(~uw-qt<p$anhJ1PZE?p3%%$G4UV1HKCLkp2!`3Q(eTo+^+uv2ABAHZ7ct z$E?dXya|T7(nu|^dZx7uU5qf~n4pQ0>(-{E=%uu3t+kZ{vT3|)Rt_V6%cVo=pVPNt z{i5ab2>&g2%Jy*!d!vuZqcM-6n-qcrxo^SvAf}B+ML$hU=Zl{{bh6i*RmZGB0Hd`u zb0T(GLg(*WV6be~cp+}?y-&rd>EnGJsdpW|6~*BZv$lt@GP+|z>qQHg5RUUv9r>zc zKoDvZw@UDdY!kFXfIYzJ*ozWUWIcXd8bpl2)x^vu%z~52F#?OgaPQO6UgMzTyd}n5 zSbo}hR%mW4b-81eg|5sb5}+X!NVcaHhcq@HubQQ}AVha5M%FvDx*f$^Va$^9?Nvac*~xEToDgEH%$aR#zic$) z(OPhvhp=ng;```$l!~n$JREWOq?s1LwNl+n4WiEi-^#YFflh}|q?C6XY#mr-CtfP8 zR6r*2UUe~@|1#ok+R!jD-A@-J3LgH-Xo4+jl8)-fPEZPYdH4_zOGc!#(|7ud^Zr!1 zoNupB_OhhbrKYwa3|y3n7x?HY?@aG^fDv1KNnocKWsv?gUs^}a^*hMWyvB&%rMv`Z zTQh_%LcW3wi|zb#2k>J^Prn0cyI$6$<@6OsuFPs81%SwbK+E#}(c5bbb#_02D#FUy z8YrFufiX90NK>Jv;ku5Au47mYJ0a}nqV)~u5M2X(tN@9SmeyiFaVbYwZ%$3>Epxp# zv0yG{JQ??Tp-H)?{%=COQLdd@4_7V^$Ja!jmF%V%^)!Iq)_YUIbd~Ia;Cn;IZZzTS z5#L!wC@M74$$BoH`wQ@fDDG152bqn1e@UQ}zD9&=J9Ix8TyyJ+WsU=2rEl2b1}0e7 z|K)h+P=v~QmNjoaP|UUBPC@E+mvUugNms^VI;C=WTQ)E|DgIaBGJBnFfyU3l_(Bb^ z^USCR9svIPItI$z721cl=Q(?y~YQVn|FGRm5T688l(nZ66u?^*0q^S@t9{z#FZf+0P z6b#lJ;n1?CrkUH`(EVgrj3Cx6F#$s(d%_}$2vSsq@V==2qkI9xX&PI9>q?ZNSz{N< z21S|Zbh|W>c2nD#@1nq2XhsvRZJ>QDz51n!w%@ znX=O4vwp*h?kS71MX93twcBu>dH2RxEtDEhkG3uj*?KE0Xd2a^o*#W@h<@P`rQQg{ z^;O-1ZEWG7g4WmZb0GUAI@Pao*vS45X4mOEn+X@vMn*`IG>&0iK5<;!NK?FV7jCT2 zl^>oo@3LOq5Fx|yFt+6iBPOj({{YXTyggZ<(88_B`&RwziD$^j1#4vammOYyt5B+5 zYulAyF^Z9qYD}~&Lh3-!3YSp>I!y<>FxR@x+XHhSoie@B3%15fdT4@Y6hm3Q4kS<| zbpqn?#c&*_l#MZE>82V3g~$}(YjEyDoLXU`E`85z8}B9!)(ai*6TR0#X@Y^fP>sYy zWylmR+q2_KN*jwihX?zhx=>mtm6ua=Gvgzl97MsrsF(ruL@-hloEKZ{zZ)E&^_+Hi>oQ#36&3q#3A zB7IU3bCOJ&kCjzJO6|55(QvrKJ&%OKLuY*wkTyTL z7bLucP=O)}B*c52hX-(;TfghJ7kBj8;YP=)9;GJpigLeSZoCwVx|&KzN+>86n*Jd) za!KV?D~{8(FoQEN;bWvYznv7(&o%~&<<$Zb9fGP}&jlG1XkuirXaY^pVJbK3?&eCj z10bK`mOjsQnM_pO{}2xe7I-j-J1Qcx+RHqZtS3t#wd}(?WMagc*-I>xVgHyKorVck3@p36 zuOn`Ad!)pj2HxWo(PUvLkMq!$3On5aykvHK7O&g0C0^f`vw2j1-@!&on$Kn_@b)D& zVs%TmWz#`ZkJ+Z~ka0>{?ORcRCYn&D5-n=VU+=*}2Yp^T;p7L}9ezYdNF+PT{xFM> zUEekyRdJK&z_M74of-1+FR!1BP|;OYG)|yy9h|(0fMUVZxA=C6Z?Pje#to3krcG8~ zn*bqomwOUoUaY{f6qOmfDWt&_*6q*OiYXn|{Z?ftMV8b`_z0Vx5k~fvad`9mft5$- zNeS@7PS}KM0!J)&k(rQum81YR5yxAY>F}(~JXxzkSy4(t5nR&t&^X}s$WrqAMcD!Q zA@(uTi1`8Q!)Bdut~Vguf}T1>2_q9b_0`hYY?Hxa8|S$*Q8_&+{|S5>&v{eUy2u1< zITL8ACT1#vQMh1Ej;;P>C6Dpta0Nr8PXM#cUT#AT0MSDls4`YFST44BdS<(e&N|wH zW&Ig_=Pym%XJzyhUeZhJ6U-R&x+kb?MHCU$12oW{eXZZALq*iE=p%nv|8CDN5ummk z_?pQG(i{F|7hBS?4C)#R9Z*U1w!6kgQDGqF+RBkCw!U=~Qjl2sn!By%aCcvsFg`Uk z4pdiH_!G(AQ;~!wH@R#8U0FW*139WxLzab{KX3vr=BAESupzBwvWhsOPzMlc?a|Dt z4W9l+*|ImA!~O!}!09#yp zSE44y`L|5yidbqPyidv|zCeVA`JC*SP&)(dAzNJEySkPIa>z`=wG<*iMH^=+$5#lf zr7n8(=y zQVEyt)4~0kw1DECicOg4?V}vXaWBz`r-jlk!tK9dzofSiz@_FNGzsnV!1RCZirm^x zTVy^nV7u^%y63)kvdY)tk+QDo)cr-?eAeT1I7rlhMM};MT95HjLeH|g7)KhbP34Z- zj28O*_O0zI;e-Hvt$9%wIq|>h1J&rYf~ZR?di8AsHwnLNHdc?;zDBjl#LXg+`u$y0 ztf#VUXFUj`8?DpRn{5>@5>t8&Q^-pf#PkB)uyL~z{*F@1bL{+@gLo+$$%&>bQ&M(*JD3%?9Q<;_D(uN37q@`B{Z|E6RhOJW(~aq_g136GdWO z_0&{QH$T!N8NIlXKUBvuZgi-(rE`e4V9SqqN|7lEy`Jo_UIzca zeG2>^9}iuPhLkl7r{`E7CY@S7j&gyYQ$7qwEZZ_#g_}k+EyAkjZ zL{cPdLlo>HI0FO29qS7%xPeY#xY4=Pl>}1g>-K$35};H5dcmDXJ<=o>r)j94PXdm( zt!JhneO#oz8%J!_C)x@@xlpm2c+Z)4UJ-VkI_yuG8XbY65_9o7eT|Suom_AX8wn7h zA))eg5M-S{Yj=pA*Q81|1QX>gZaOt1><}w_m!sp4tBYDV{X@-+CfOg- zdDiI$aR6b+NhQLPru?r))3ZvHSxs52<;n&%q}m1-H7z7C#rW_kDd#1pMNMp6E*kmP z&VtB_Xgi|KsvzR(4z7YlT(r9$8I(v#gDXd(`BDzq~Ka|z0AVk0Ns0d=W zE)btRQQ&94eql;{#lF#HcSAS%2|yR@2od-u4*kL-gI+?LHimsBQWs{SqC4@(1kXCz z6>ZkaeTp05HpF<3*X&tigf$O$X*VfLw#-C2JYPt*3;9Yu;(*Au;Vwvl4%l&FDUV>> zjnf*ckBTg&ZHzhu&q%oVV}dtq&=_SpfV#l!U#uaAM0FMBHykf1Lg!>Y(PL4e7O17x z{3%KrBg#{)3ZP9f`Gptydx3m30*+Mb!CX^TvC6y#CbeveM^q#OdGRb(g=Q+mlB_&y zz?1jkr7jz2R=#_w05%wVIjQE2bHcAGR zo>f=DS{MKM9%n`cm71#I^L|}9ea0?TN@=VuQK~0Ow8H`X_nZG*Y=% ziJmx3ew4Z?nc$C4-h!Z<8kDhh1tHE=8Wvi&0g?b#GRA@kKv|QrkQLa&sU_981KhFc z3dDRH@0j(1#|?GZuj`xARub8>0tQ%iMhyilF?3uXdfvy-;~TmG0BDNsyB!Ul{xQ9k zmGoMJ_d4Vf_UO5)M|GF;V5vjg6_Cmmh&s`^L>emnPr)j9WVO^9%!Ho&H&f};ra^ym z73xDYgazCnOCX#>MqKKj!n($s#o1=>FaVL(=f4%;^Hb7(VHYGv>7PSV2zE;C>?}$n zzV%A1+l1_DzC+1EStUCwpDop>oa*)5#vgUBE};kw9?0EbO<$1K?a*{w5&h3u9r%II z%TD7NSQoe1;SIIZ>K%SbFQ{!gx0^8tdFgxFoxR%rIf0q8Cl7OxR8zF1F^V6dl%92x z)Di*(dXPU4&CQAM%3Aa+8QVn)d>@`kcn|e_hr4Olzh**xaSWDYngIfMV` z5X3MtXi@#)hGsZLdIklId26&guc5C&0_Dcq@rK0lB1ib8)p>U~W@|6R{qIX#`#Bd;L6pJkggQ9qOSW8)8em1HG? z@2ba{@mLFri)%5T3YC?m;8$%W9em;0Z_`mN(gq;%65_;#+=JdLK;W^S32f#3>YLv6 za?cHizok*W){5t^kwX~mbMtXX9N6?+n{xmhg%dT!A|{Yzk%Y7q@`aEfS=z8zqnTSB z130!gI(WveywOeFCtuB^bznC2pg-Lp#7D32u>3$K44_a|P${S!`fWlG2ZfGIkzjO? zScc@b^Ei4dG%o)YWC>tK;`vKAHS!`IK77%}Qk;Mo{Rz|{=DPCJW zSzAr!CU^f{&fau=fc@Fze%DpnU-DvN_73(WOQZj%@b>Tbyz4)6?(A68A32_;PNi~c zo4QR?C>}x3dU)g)H`!cxprM-*D_%iXLP9wpx(KJr{VlT^TA--&!5ia3SG#3LDlYJC z$;N{D;lbM>IILn~jBExMydbCQE3?q-ArFJSV;E6sYtI_D1{j|r8=k&XBer`v zaR#UsDMp2&c`@)~O_ z2kq7URrX+8SzDSE6W*)~wR0^25@&6t69NbAK~V2ru%O>gJnCqrZ9Gw#&(h(uB0TEw z>BP4>$kVFPIW)7Af|2W@2)an*8;&_N*3ksFI=f;Qt<+rvKiMHNcUudLrzTlI!tJev z$=WVjEqNV|E;Q=)vMY1E#q-uQ{t!Hs8L~s;Hh!-|SYv=^X2_t)7)M!SY;4n%4B5+X z=-zd)k0=hZ(8s7MInyTc)oAd=iquSy#pr^UR z)Q=A)r|->)(~M?^zl^A}{+KWJv^u#lGk(vd$V3+gf# z395y!BKIo9LLb~-9IG?FCrFYtzSRJ3_5DbhLzeTb_DL&uqX)`%Gecu;SPX%G5o_6x z5{kZtT6G-86USoV00)T&psprE`=i=l%^5xnaPa8Z5zH6V+*oHtgdzLG_spT%(O!!# zM_>*Uj%~P#_^!PChIO^pk~@ME95}o`kb@_zztH01(;AqYXRwu0g+H0mb`Qn^Uws77 z#bk(`hfA}z>1<$CALj*iRfRur&ALs|=V2b6A|d#*09^IXB&uX>Pr|{Y`oTEAzfeA8 zzKW_cKaIR)Mqg)y2T0qkaaDeB74b_39>WzgN~JApZFB{Txt{Y6jzLY)!@RRF!L5QJ zCkS6R$mz6dM_Tl)czx8c>}-x@9ncXGJhUnbPtqC28Fzx{d;H@-f^26&(;ariz^yJK zr}DCo)NA*(%JXS*+q(gC-4cXi431kDpwlt$9xP%YMP=QKuX$O~j zM41mylN<0|jKfCxLci5pJn1e_kt@J%?NWjM7w{WGlKIrIQGz)IW~ujO1{Je#bd=Vz zhVtqx9rPWcd%xg*(X~S77r|DF85Ic!*P7+{xy`>yvm_iILfZeF_hg>hB}i_KeLW-p z$0C-SDF?rMkE1@nsMF|F>~T)!l+Nu(H z{Lp`lP_8hz5KQXN^cRvK3- zJYvp^cUQltVL0{VI_7ncchW%@x?q^DU85imsXd&d28UUAuY+W<kTLBmHTNdC%<| zbMg&p2Q^a(ba%#5SvyNqO`F4*Ic5_alc5$G)2_kpOeV6j&O8PAaw<6NYEA(=ZHghxD@i& z&4Ym?fY7}dUv1|*fP+XB@6!))=qN~P;UG2uzLmM;(~lKARv$U_6r341pV?A9i^$ww zxufx^mPdDCT*Asq{pF;-$d2K2HIJA$#WzU}noo15+GlI*iR*k&CsTTQ=Ue?L4QvrX z$IYSSzo4G|Lmh6y6w)9z&s)&f4D#S}k=LB9r^Judr zvpi?8x`%%a#*nEUF!Z*iWS2{V$C=Kouhu4lwaVLW^S$VPvv0(+Eh|lYvdDZv=E|at zI4@>Zk0C7f9_H|4iF-UIFWF{vEn**Ed423s?HHnJM)QS37P>gDv<2)^S&O41xs7K7 zb`vL=5^G_c%tz1!!lGyY2p3y^jcrQRP2bW7v!&2E9zLNKXH?!4Nyidg!QxeM7I(jL zq!_)mUwA1|`-UgwtuNN;7Z)yFj;7=vY6L}$?Fn>8`0+@&Spqa!&#TcA^Ymhs4ARk( z3}QQLYPd%H)x^z?5fyl$`er{719QRPd~REZ*Ry=w8)i5L9~f{{)$tE}VagB;aK*Ce zaVZWVQcfY87(OwDO#(#Orl++SQY5#n)|S5$KrR0==)V|Cb50aRnpITCFNi7&CN)GW zz!uEE7hnpheQhb>MV+Ex=-7k=Y{UhYG^t3F$*C5mK|45txw!mI`>=DjsJ>{$De|4J z{!aIfhi@xSYuQ2LbppZD-4DZ%h(_+UihD41XdjC7dU7-A;p=xT9nI`f<*0QWp^6kW zrAvGS3QLTdvo2gl{yfD)sq$2fAa!2}ahK3@t=A_!N?HC2BlYpxyDGM+WY!R;GAB&DHdDVtxk}EO5Tz z4gR7<#I7jR=YiDiFi$EC&gab<_Wqm&&gx-~N+ssh&*%l%NNr~D&?Tw6v|G#y5t6v9 zOP=MR;P0Hniv1qdXPqlDRHZF0udKjnC(&^CuZtUiSYYbh#-L$Ibk!XYp(+rV)s2;a z@oOfuGdI|lVtP>V?Qm_ut2)&7r<=iH+Fy3O8S*Qc1Zx3}0%xtgf#qT0Z?qOpoSuv0C!GicTXKU1M}# zu$JVmaq{4ts!ZtjXl_DRS1yXbLXRGs<_MvIVRSmRF}h_4D^qe#yns1Uh4umM2A(d z@o5{iVo~2V;o;HDqYi>8ZL>oU!^Cyc>qJ#FHPg+RN^;wHemiJ)wPIsTH<1wsp1}wb z-!l}Q=t40l+;qVq^G27tE1jy74HD@GL|^DUAM;Ddz2g?Y6FGREo09}`kk5m~md!@y z-fcJdXm}Tr3|B?UlFkZ3U04*FUG?GDuBUwD#91uEWK*foYWLb2Lb-$##+kOlQDfHM z_S|SERW0j;HxGG-@$LYc#YNocy+y}#nuVWntiD>ckK)2mX(>c|SOhj6+v=EW&_UiA+@tTAToIjJQLSH*PHym+$#$HFuSX*>VnJ#V{{}mHM60$fk~wW zb)bklps;H&`=k@+yao|@xdAy)#v0;jHCQ3(V#6V=B4?tCm9`*V4X2AH&Pt7%#nIT32=X9V}3^!8B0Bn9s+ zpxwT_bWJ^qIJZ#60g3o6NZ?mbdfgl72DCv(La2vW5b6f;yZ91-DIq9yIVjSeTzptL}Xh z@Kjlz-h#U%J-^Y)Y2f)%1TWD<>%%EA~j{VBSkev%rjK- zJ$#d*O|q+G$Br9YxoxPWO{j-4bm98jZ!pdg3VO`KDnEo#EQtNF>t6sjW5MZ)^upXv z)(}6}hx_N&s|7eMx9ZyPs(jTf`6LT-xp&$^AC5B5n}s1!3V9a$(+OQEZ{Eef%9x*p z*Tj}46L+-Ii=hw2Wa8!!BS?Ur+-h~fxTC!RxMis-uw!Norxn0GLr8}nFH@c#gm6z% zv;ooAe3jpkXB-&nPxp#Cp1up8h~H}dKS2n?rxIKF20{NDg#V1IH?cMTFC47f?h}0{ zA*ipp)wamr5{p+zs@`tBiMEC7&T3aHF-6(GJ-vKV?&r;yoI7l zXM@H^z;r=uWy9k2)rC=R*YsZNwU453NRblctJv2=m=*N&AH6ld8A-Sg1e1?3K~?t| zg)9@za={X-a1g_laf{WVNe#Rrz(R=PDa-6AjzGOuA7gaNz{n&qKjt9u6M<9X@jVoZ zqTolbfRrLpNLV^rVsGh>z*Xv6K9UbjU z_@n}`#9`Ws4mp&Lx$3UKF|l_|nK2TGZ9d0%jU{{zRtNl8icYy@%lL3hxNDfg?qZP% zuvLZi1zFQ-{bWRbz!zkYED@#hRNg0w+5JM4_FiO#NqA(jny4b;JXJZ>qInyrPO<}^ z!rpBQ!%6zV=76R{#%fg#iYv{MC<)KG0n_7O{Lp4}^dQsdo7`mM0Y_IG`?k1R2e^M{ zpLO!eDiLLk;G=)HX?P4u$KAjoK+lNW@#Kw^hri+W<0R+R!(cPgWFoR{Sa&p^29$Fi zmT4f^fSx~8`sZf10*Sm31raXztPG7YXi(27GQ+9oA_KIF6a!QeS;?5LG@&f_?gKP* zYgKkiax}@YF#wvNJPna76OVe*3xrAsn$m@Og`EJhH*@|Rh}!a?Zd#!;tEmpMf8)Sp zI#}fTKRJ;5Hx6dWN)5j`DF06m=6%4ph81#IK>w42Q`XxEmvm&gZw?G00xzl4=yM4L znJjhd)?(<(bCWX==T44sTCQBX++9CR&7}>KO53>qT84s5``)<~_o`dqYO-}G(t7uyqU8r(NSTdOXet6_WyGoXr_}FxA&Y1k% zm(baqkNyMjZhZMK=_N4#?qCoDy|c5XZNY&6{j;I}$9Q04Vr*f+U}0lmX2L{oZ)+B= zASVtFgY(Z_@RAZDNc4luPD!;ulmPEYfcTy?5m!oQ&k@<{+l0$w{E{)4L`wwADb5@rY-8E&pOD-aOE=x<5 zFNj|pcVS|fKPkCaZoe@8`xEi8VM1gpGG`7=UbGq-Gd-OXhY0Qd_%aA<3YJwXmUGeK z|4DvzPQCkE8OKOL$;K-AhLEn+-LE2>&3gM>*meQXdSEcG*TQf``X5h5h6(AL%P$n{ zY^};v^IrMI_8=HdKp9P7-UwC6^TVbr$(67+px>_uSyb(3fuQhNI>o~!*~3U<%2Thc zGT~LqU44I>yG&IV0A}5Tzr5Qh?E)<7Gn|WtCoLW<%Ys{!_0n`x%n?Nv^&=>Eu`?yRa+{H@@BBU z1aWyAj3_>gaX0P5qx`GefaXLg|H(VvN#jh(-+BDd)M~31$fR*v=zt0^qR1QE^LC(T}avMNKf3j9`W&GS; zPZ8ABrvFaI1Okd%{SS@0ME~ypvU2u6jk&J#-!Coa!΄L59FR*`GUzx$XQ_A26K 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

    tG`GyzEF(2)c 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

    wX8BLHTY>k%TEsqkRM#? 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

    <3uH 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

    pIye5 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

    ;v5t<=opB5{)1 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 Date: Sat, 11 Oct 2025 15:19:52 +0800 Subject: [PATCH 14/14] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=B0=E8=BF=9C=E7=A8=8B=20zrp=5Fbranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 第四周实践任务.docx | Bin 0 -> 12459 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 第四周实践任务.docx diff --git a/第四周实践任务.docx b/第四周实践任务.docx new file mode 100644 index 0000000000000000000000000000000000000000..388c5f4b0a07d47e8ae354ce5a06a7cb0467278b GIT binary patch literal 12459 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 literal 0 HcmV?d00001