16 | -- EOF -- 17 |
18 | {% include 'inclusions/_donate.html' %} 19 | {% include 'blog/inclusions/_tags.html' %} 20 | 21 | {% block related_posts %}{% endblock related_posts %} 22 |├── config ├── __init__.py ├── settings │ ├── __init__.py │ └── test.py ├── asgi.py └── wsgi.py ├── blogproject ├── __init__.py ├── alerts │ ├── tests.py │ ├── views.py │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_alert_scopes.py │ │ └── 0001_initial.py │ ├── apps.py │ ├── admin.py │ └── models.py ├── core │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ └── __init__.py │ ├── tests │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── models.py │ │ └── factories.py │ ├── apps.py │ ├── models.py │ ├── decrators.py │ └── views.py ├── tags │ ├── __init__.py │ ├── views.py │ ├── tests │ │ ├── __init__.py │ │ └── factories.py │ ├── migrations │ │ └── __init__.py │ ├── apps.py │ ├── admin.py │ └── models.py ├── users │ ├── views.py │ ├── __init__.py │ ├── tests │ │ ├── __init__.py │ │ └── factories.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── create_tokens.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0002_auto_20200919_1157.py │ ├── apps.py │ ├── serializers.py │ ├── adapter.py │ ├── models.py │ └── admin.py ├── comments │ ├── utils.py │ ├── tests │ │ ├── __init__.py │ │ ├── factories.py │ │ └── test_forms.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0003_auto_20200920_1835.py │ │ └── 0002_blogcomment_user.py │ ├── templatetags │ │ ├── __init__.py │ │ └── comments_extras.py │ ├── urls.py │ ├── apps.py │ ├── __init__.py │ ├── admin.py │ ├── forms.py │ └── serializers.py ├── courses │ ├── __init__.py │ ├── signals.py │ ├── tests │ │ ├── __init__.py │ │ ├── factories.py │ │ └── test_templatetags.py │ ├── migrations │ │ └── __init__.py │ ├── templatetags │ │ ├── __init__.py │ │ └── courses_extras.py │ ├── static │ │ └── courses │ │ │ └── images │ │ │ └── pay │ │ │ ├── alipay0.jpg │ │ │ ├── alipay99.jpg │ │ │ ├── alipay199.jpg │ │ │ ├── alipay299.jpg │ │ │ ├── alipay599.jpg │ │ │ ├── wechatpay0.png │ │ │ ├── wechatpay99.png │ │ │ ├── wechatpay199.png │ │ │ ├── wechatpay299.png │ │ │ └── wechatpay599.png │ ├── apps.py │ ├── search_indexes.py │ ├── urls.py │ └── managers.py ├── favorites │ ├── __init__.py │ ├── tests │ │ ├── __init__.py │ │ └── factories.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_auto_20200920_1601.py │ │ ├── 0003_auto_20200920_1604.py │ │ └── 0004_auto_20210411_1737.py │ ├── apps.py │ ├── urls.py │ ├── admin.py │ └── views.py ├── friendlinks │ ├── tests.py │ ├── views.py │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ ├── apps.py │ ├── admin.py │ └── models.py ├── notify │ ├── __init__.py │ ├── templatetags │ │ ├── __init__.py │ │ └── notify_tags.py │ ├── context_processors.py │ ├── urls.py │ ├── factories.py │ └── views.py ├── scripts │ ├── __init__.py │ └── fake │ │ ├── _tags.py │ │ ├── __init__.py │ │ ├── _allauth.py │ │ ├── _mediums.py │ │ ├── _users.py │ │ ├── _friend_links.py │ │ ├── _recommendations.py │ │ ├── _course_categories.py │ │ ├── _issues.py │ │ ├── _superuser.py │ │ ├── _post_categories.py │ │ ├── _favorites.py │ │ ├── _courses.py │ │ ├── _posts.py │ │ ├── _materials.py │ │ ├── all.py │ │ ├── _comments.py │ │ └── _clean_db.py ├── taskapp │ ├── __init__.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ └── __init__.py │ ├── tasks.py │ └── celery.py ├── webtools │ ├── __init__.py │ ├── admin.py │ ├── models.py │ ├── tests.py │ ├── migrations │ │ └── __init__.py │ ├── apps.py │ ├── urls.py │ ├── views.py │ └── forms.py ├── blog │ ├── tests │ │ ├── __init__.py │ │ ├── test_utils.py │ │ └── factories.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0005_remove_post_tags.py │ │ ├── 0003_post_meta_ordering.py │ │ ├── 0006_post_tags.py │ │ ├── 0007_auto_20210411_1737.py │ │ └── 0004_auto_20200306_1047.py │ ├── templatetags │ │ ├── __init__.py │ │ └── blog_extras.py │ ├── __init__.py │ ├── static │ │ └── blog │ │ │ └── images │ │ │ ├── ad.jpg │ │ │ ├── alipay.jpg │ │ │ ├── aliyun.jpg │ │ │ ├── logo.png │ │ │ ├── upyun_logo.png │ │ │ ├── weixinpay.jpg │ │ │ └── tencentcloud.jpg │ ├── search_indexes.py │ ├── apps.py │ ├── urls.py │ ├── feeds.py │ ├── sitemaps.py │ ├── utils.py │ └── managers.py ├── newsletters │ ├── __init__.py │ ├── tests │ │ ├── __init__.py │ │ └── test_view.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ ├── apps.py │ ├── admin.py │ ├── urls.py │ ├── models.py │ └── forms.py ├── functional_tests │ └── __init__.py ├── templates │ ├── blog │ │ ├── inclusions │ │ │ ├── _toc_content.html │ │ │ ├── _tags.html │ │ │ ├── _ad.html │ │ │ ├── _sidebar_mobile.html │ │ │ ├── _toc.html │ │ │ ├── _friend_link.html │ │ │ ├── _related.html │ │ │ ├── _recommendation.html │ │ │ ├── _medium.html │ │ │ ├── _donate.html │ │ │ ├── _detail.html │ │ │ ├── _pagination.html │ │ │ └── _entry_list_item.html │ │ ├── category.html │ │ ├── index.html │ │ ├── category_list.html │ │ ├── detail.html │ │ ├── archives.html │ │ └── donate.html │ ├── search │ │ ├── indexes │ │ │ ├── blog │ │ │ │ └── post_text.txt │ │ │ └── courses │ │ │ │ └── material_text.txt │ │ ├── search.html │ │ └── _search_entry_list_item.html │ ├── 503.html │ ├── comments │ │ ├── email │ │ │ ├── comment.txt │ │ │ ├── reply.txt │ │ │ ├── reply.html │ │ │ └── comment.html │ │ └── inclusions │ │ │ └── _comments_app.html │ ├── courses │ │ ├── course_detail.html │ │ ├── inclusions │ │ │ ├── _description.html │ │ │ ├── _sidebar_mobile.html │ │ │ ├── _prev_next.html │ │ │ ├── _sidebar_desk.html │ │ │ ├── _course_list_item.html │ │ │ ├── _material_meta.html │ │ │ └── _toc.html │ │ ├── material_detail.html │ │ └── base.html │ ├── notifications │ │ ├── comment.html │ │ ├── inclusions │ │ │ ├── _comment.html │ │ │ └── _reply.html │ │ ├── reply.html │ │ ├── base.html │ │ └── list.html │ ├── account │ │ ├── login.html │ │ └── inclusions │ │ │ └── _login.html │ ├── inclusions │ │ ├── _simple_pagination.html │ │ └── _footer.html │ └── sidebar_mobile_base.html ├── database │ └── README.md └── conftest.py ├── devops └── ansible │ ├── backup.yml │ ├── restore.yml │ ├── roles │ ├── redis │ │ └── tasks │ │ │ └── main.yml │ ├── nginx │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── supervisor │ │ └── tasks │ │ │ └── main.yml │ ├── postgresql │ │ └── tasks │ │ │ └── main.yml │ ├── project │ │ ├── tasks │ │ │ ├── deps.yml │ │ │ ├── envfile.yml │ │ │ ├── main.yml │ │ │ ├── repo.yml │ │ │ ├── management.yml │ │ │ ├── supervisor.yml │ │ │ ├── nginx.yml │ │ │ └── db.yml │ │ ├── templates │ │ │ ├── nginx │ │ │ │ ├── proxy.conf.j2 │ │ │ │ └── blogproject.conf.j2 │ │ │ └── supervisor │ │ │ │ ├── blogproject-celery-worker.conf.j2 │ │ │ │ ├── blogproject-celery-beat.conf.j2 │ │ │ │ └── blogproject.conf.j2 │ │ └── handlers │ │ │ └── main.yml │ ├── poetry │ │ └── tasks │ │ │ └── main.yml │ ├── pipx │ │ └── tasks │ │ │ └── main.yml │ └── pyenv │ │ └── tasks │ │ └── main.yml │ ├── hosts.yml │ ├── site.yml │ └── group_vars │ └── all.yml ├── frontend ├── src │ ├── scripts │ │ ├── donate.js │ │ ├── search.ts │ │ ├── backtop.ts │ │ ├── toc.ts │ │ └── offcanvas.ts │ ├── axiosService.js │ ├── style │ │ ├── _tasklist.scss │ │ ├── _favorite.scss │ │ ├── _pagination.scss │ │ ├── _util.scss │ │ ├── _login.scss │ │ ├── _aside.scss │ │ ├── _literal.scss │ │ ├── _alert.scss │ │ ├── _header.scss │ │ ├── _backtop.scss │ │ ├── _hilite.scss │ │ ├── _widget.scss │ │ ├── _post.scss │ │ ├── _tabbed.scss │ │ ├── _menu.scss │ │ ├── _notification.scss │ │ ├── _offcanvas.scss │ │ ├── _donate.scss │ │ ├── _toc.scss │ │ ├── _sidebar.scss │ │ ├── _navbar.scss │ │ └── _course.scss │ ├── shims-vue.d.ts │ ├── images │ │ ├── error-warning-fill.svg │ │ ├── information-fill.svg │ │ ├── alert-fill.svg │ │ └── lightbulb-line.svg │ ├── main.ts │ ├── api.js │ ├── styles.scss │ └── components │ │ └── CommentList.vue ├── .browserslistrc ├── build │ ├── favicon.ico │ ├── img │ │ ├── error-warning-fill.027f8c93.svg │ │ ├── information-fill.dfcc3b8f.svg │ │ ├── alert-fill.bbcee1b1.svg │ │ └── lightbulb-line.a44c3828.svg │ ├── index.html │ └── manifest.json ├── public │ ├── favicon.ico │ └── index.html ├── .prettierrc ├── manifest-test.json ├── README.md ├── babel.config.js ├── tsconfig.json ├── .eslintrc.js ├── package.json └── vue.config.js ├── .dockerignore ├── docs ├── tag.md ├── friendlink.md ├── img │ ├── logo.png │ ├── add_post.png │ ├── add_course.png │ ├── friendlink.png │ ├── post_brief.png │ ├── add_category.png │ ├── add_material.png │ ├── admin_index.png │ ├── configuration.png │ ├── course_detail.png │ ├── course_list.png │ ├── blog_post_list.png │ ├── course_category.png │ ├── blog_category_list.png │ ├── blog_category_nav.png │ └── admin_course_category_list.png ├── index.md ├── overview.md ├── category.md ├── configuration.md ├── post.md └── course.md ├── screenshot.png ├── compose ├── local │ ├── django │ │ ├── celery │ │ │ ├── worker │ │ │ │ └── start.sh │ │ │ └── beat │ │ │ │ └── start.sh │ │ ├── start.sh │ │ └── Dockerfile │ └── node │ │ └── Dockerfile ├── production │ ├── django │ │ ├── celery │ │ │ ├── worker │ │ │ │ └── start.sh │ │ │ └── beat │ │ │ │ └── start.sh │ │ ├── start.sh │ │ └── entrypoint.sh │ ├── postgres │ │ ├── maintenance │ │ │ ├── _sourced │ │ │ │ ├── constants.sh │ │ │ │ ├── yes_no.sh │ │ │ │ ├── countdown.sh │ │ │ │ └── messages.sh │ │ │ ├── backups │ │ │ └── backup │ │ └── Dockerfile │ ├── nginx │ │ ├── includes │ │ │ └── proxy.conf │ │ ├── Dockerfile │ │ ├── DockerfileMainland │ │ └── conf.d │ │ │ └── blogproject.conf-tmpl │ └── statusok │ │ └── config │ │ └── config.example.json └── external │ └── django │ └── DockerfileMainland ├── .envs └── .local │ ├── .django │ └── .postgres ├── setup.cfg ├── README.md ├── mkdocs.yml └── manage.py /config/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/alerts/tests.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/alerts/views.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/core/admin.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/tags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/tags/views.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/views.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/settings/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /devops/ansible/backup.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /devops/ansible/restore.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/alerts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/comments/utils.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/courses/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/courses/signals.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/favorites/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/friendlinks/tests.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/friendlinks/views.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/notify/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_tags.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/taskapp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/webtools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/webtools/admin.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/webtools/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/webtools/tests.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/scripts/donate.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/blog/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/comments/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/courses/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/friendlinks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/newsletters/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_allauth.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_mediums.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_users.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/tags/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/alerts/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/blog/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/blog/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/comments/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/core/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/courses/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/favorites/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/functional_tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/newsletters/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/notify/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_friend_links.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/tags/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/taskapp/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/webtools/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .* 2 | frontend/node_modules/* 3 | -------------------------------------------------------------------------------- /blogproject/comments/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/courses/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/favorites/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/friendlinks/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/newsletters/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_recommendations.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/taskapp/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/users/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /blogproject/blog/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = "blog.apps.BlogConfig" 2 | -------------------------------------------------------------------------------- /blogproject/comments/urls.py: -------------------------------------------------------------------------------- 1 | app_name = "comments" 2 | urlpatterns = [] 3 | -------------------------------------------------------------------------------- /blogproject/core/tests/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = "core.tests.apps.TestsConfig" 2 | -------------------------------------------------------------------------------- /blogproject/templates/blog/inclusions/_toc_content.html: -------------------------------------------------------------------------------- 1 |
服务暂不可用
9 | 10 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 88 3 | extend-ignore = E203 4 | exclude = 5 | .tox, 6 | .git, 7 | */migrations/*, 8 | */static/CACHE/*, 9 | docs, 10 | node_modules 11 | -------------------------------------------------------------------------------- /blogproject/tags/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class TagsConfig(AppConfig): 6 | name = "tags" 7 | verbose_name = _("Tags") 8 | -------------------------------------------------------------------------------- /blogproject/alerts/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class AlertsConfig(AppConfig): 6 | name = "alerts" 7 | verbose_name = _("Alerts") 8 | -------------------------------------------------------------------------------- /devops/ansible/roles/project/tasks/envfile.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy envfile 3 | ansible.builtin.template: 4 | src: blogproject.env.j2 5 | dest: "{{ project_path }}/blogproject.env" 6 | notify: 7 | Restart program -------------------------------------------------------------------------------- /blogproject/courses/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class CoursesConfig(AppConfig): 6 | name = "courses" 7 | verbose_name = _("Courses") 8 | -------------------------------------------------------------------------------- /compose/local/node/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-stretch-slim 2 | 3 | WORKDIR /app 4 | 5 | COPY ./frontend/package.json /app 6 | 7 | RUN npm install && npm cache clean --force 8 | 9 | ENV PATH ./node_modules/.bin/:$PATH 10 | -------------------------------------------------------------------------------- /blogproject/comments/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class CommentsConfig(AppConfig): 6 | name = "comments" 7 | verbose_name = _("comments") 8 | -------------------------------------------------------------------------------- /frontend/src/style/_tasklist.scss: -------------------------------------------------------------------------------- 1 | .task-list .task-list-item { 2 | list-style-type: none !important; 3 | } 4 | 5 | .task-list .task-list-item input[type="checkbox"] { 6 | margin: 0 4px 0.25em -20px; 7 | vertical-align: middle; 8 | } -------------------------------------------------------------------------------- /blogproject/comments/__init__.py: -------------------------------------------------------------------------------- 1 | def get_model(): 2 | from .models import BlogComment 3 | 4 | return BlogComment 5 | 6 | 7 | def get_form(): 8 | from .forms import BlogCommentForm 9 | 10 | return BlogCommentForm 11 | -------------------------------------------------------------------------------- /blogproject/friendlinks/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class FriendlinksConfig(AppConfig): 6 | name = "friendlinks" 7 | verbose_name = _("Friend Links") 8 | -------------------------------------------------------------------------------- /blogproject/templates/comments/email/comment.txt: -------------------------------------------------------------------------------- 1 | {{ comment.user.name }} 在 {{ content_object.title }} 中发布了评论: 2 | 3 | {{ comment.comment_html | safe }} 4 | 5 | 请复制以下链接到浏览器打开: 6 | {{ link }} 7 | 8 | ----------------------- 9 | 发自:{{ site.name }} -------------------------------------------------------------------------------- /frontend/src/style/_favorite.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | .issue { 4 | .issue-date { 5 | margin-right: $width-gap-half; 6 | } 7 | } 8 | 9 | .tag { 10 | font-size: $font-size-small; 11 | margin-right: $width-gap-half; 12 | } -------------------------------------------------------------------------------- /.envs/.local/.postgres: -------------------------------------------------------------------------------- 1 | # PostgreSQL 2 | # ------------------------------------------------------------------------------ 3 | POSTGRES_HOST=postgres 4 | POSTGRES_PORT=5432 5 | POSTGRES_DB=blogproject 6 | POSTGRES_USER=debug 7 | POSTGRES_PASSWORD=debug 8 | -------------------------------------------------------------------------------- /blogproject/templates/comments/email/reply.txt: -------------------------------------------------------------------------------- 1 | {{ comment.user.name }} 在 {{ content_object.title }} 中回复了你: 2 | 3 | {{ comment.comment_html | safe }} 4 | 5 | 请复制以下链接到浏览器打开: 6 | {{ link }} 7 | 8 | ----------------------- 9 | 发自:{{ site.name }} 10 | -------------------------------------------------------------------------------- /blogproject/templates/courses/course_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'courses/base.html' %} 2 | {% load comments static %} 3 | {% load courses_extras %} 4 | 5 | {% block article %} 6 | {% include 'courses/inclusions/_description.html' %} 7 | {% endblock article %} -------------------------------------------------------------------------------- /blogproject/templates/blog/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/index.html' %} 2 | 3 | {% block description %} 4 | {% if category.description %} 5 | 6 | {% endif %} 7 | {% endblock description %} -------------------------------------------------------------------------------- /blogproject/newsletters/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Subscription 4 | 5 | 6 | @admin.register(Subscription) 7 | class SubscriptionAdmin(admin.ModelAdmin): 8 | list_display = ["id", "user", "email", "confirmed", "active"] 9 | -------------------------------------------------------------------------------- /blogproject/scripts/fake/_issues.py: -------------------------------------------------------------------------------- 1 | from favorites.tests.factories import IssueFactory 2 | from tags.tests.factories import TagFactory 3 | 4 | 5 | def run(): 6 | IssueFactory.create_batch(40, tags=[TagFactory(), TagFactory()]) 7 | print("Issues created!") 8 | -------------------------------------------------------------------------------- /blogproject/database/README.md: -------------------------------------------------------------------------------- 1 | 为了兼容 Docker,默认的 sqlite 数据库生成在项目根目录的 database 目录下,因此在生成数据库之前需要确保项目根目录下 database 文件夹的存在。否则在生成数据库时会报错: 2 | 3 | ``` 4 | django.db.utils.OperationalError: unable to open database file 5 | ``` 6 | 7 | 如果使用 MySQL、PostgreSQL 等数据库引擎,则 database 文件夹可有可无。 -------------------------------------------------------------------------------- /docs/overview.md: -------------------------------------------------------------------------------- 1 | ## 登录博客后台 2 | 假设博客部署域名为 zmrenwu.com,则后台的入口在 zmrenwu.com/admin/。 3 | 4 | 浏览器打开入口地址,输入 superuser 的账户和密码即可登录博客后台,对博客的内容进行管理。 5 | 6 | 下面是登录后的页面: 7 | 8 |  9 | 10 | 博客系统中的大部分数据都可以在后台进行增删改查。红色方框重点标出了博客内容管理模块,下面来逐一介绍。 -------------------------------------------------------------------------------- /blogproject/scripts/fake/_superuser.py: -------------------------------------------------------------------------------- 1 | from users.models import User 2 | 3 | 4 | def run(): 5 | User.objects.create_superuser( 6 | username="admin", password="test123456", email="admin@example.com", name="admin" 7 | ) 8 | print("Superuser 'admin' created.") 9 | -------------------------------------------------------------------------------- /frontend/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | declare module '*.vue' { 3 | import type { DefineComponent } from 'vue'; 4 | const component: DefineComponent<{}, {}, any>; 5 | export default component; 6 | } 7 | 8 | // declare module './scripts/backtop.js'; 9 | -------------------------------------------------------------------------------- /blogproject/tags/tests/factories.py: -------------------------------------------------------------------------------- 1 | import factory 2 | from factory.django import DjangoModelFactory 3 | from tags.models import Tag 4 | 5 | 6 | class TagFactory(DjangoModelFactory): 7 | name = factory.Faker("uuid4") 8 | 9 | class Meta: 10 | model = Tag 11 | -------------------------------------------------------------------------------- /blogproject/templates/blog/inclusions/_tags.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /compose/production/postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:12.3 2 | 3 | COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance 4 | RUN chmod +x /usr/local/bin/maintenance/* 5 | RUN mv /usr/local/bin/maintenance/* /usr/local/bin \ 6 | && rmdir /usr/local/bin/maintenance 7 | -------------------------------------------------------------------------------- /blogproject/comments/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django_comments.admin import CommentsAdmin 3 | 4 | from .models import BlogComment 5 | 6 | 7 | @admin.register(BlogComment) 8 | class BlogCommentAdmin(CommentsAdmin): 9 | list_select_related = ["user"] 10 | -------------------------------------------------------------------------------- /frontend/src/images/error-warning-fill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/images/information-fill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /compose/production/django/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python manage.py collectstatic --noinput 4 | python manage.py compilemessages 5 | python manage.py migrate 6 | python manage.py setup_periodic_tasks 7 | gunicorn config.asgi:application -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 --chdir=/app -------------------------------------------------------------------------------- /frontend/build/img/error-warning-fill.027f8c93.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/build/img/information-fill.dfcc3b8f.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/notify/context_processors.py: -------------------------------------------------------------------------------- 1 | def notification_count(request): 2 | user = request.user 3 | 4 | if user.is_anonymous: 5 | unread_count = None 6 | else: 7 | unread_count = user.notifications.unread().count() 8 | 9 | return {"unread_count": unread_count} 10 | -------------------------------------------------------------------------------- /devops/ansible/roles/nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure Nginx is installed 3 | ansible.builtin.package: 4 | name: nginx 5 | state: present 6 | 7 | - name: Remove default conf 8 | file: 9 | path: /etc/nginx/sites-enabled/default 10 | state: absent 11 | notify: Restart nginx -------------------------------------------------------------------------------- /frontend/src/images/alert-fill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/style/_pagination.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | .pagination { 4 | list-style: none; 5 | padding-left: 0; 6 | 7 | .pagination-item { 8 | display: inline-block; 9 | padding: 0 $width-gap-half; 10 | } 11 | 12 | .active a { 13 | color: $color-text; 14 | } 15 | } -------------------------------------------------------------------------------- /blogproject/scripts/fake/_post_categories.py: -------------------------------------------------------------------------------- 1 | from blog.tests.factories import CategoryFactory 2 | from users.models import User 3 | 4 | 5 | def run(): 6 | admin_user = User.objects.get(username="admin") 7 | CategoryFactory.create_batch(10, creator=admin_user) 8 | print("Post categories created.") 9 | -------------------------------------------------------------------------------- /frontend/build/img/alert-fill.bbcee1b1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blogproject/favorites/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | app_name = "favorites" 6 | urlpatterns = [ 7 | path("issues/", views.IssueListView.as_view(), name="issue_list"), 8 | path("issues/暂无文章
11 | {% endfor %} 12 | {% if is_paginated %} 13 | {{ page_obj.render }} 14 | {% endif %} 15 |4 | {{ comment.user.name }} 在 {{ content_object.title }} 中回复了你: 5 |
6 |{{ comment.comment_html | safe }}
7 | 8 |如果点击无效,请复制以下链接到浏览器打开:
{{ link }}
11 | 发自:{{ site.name }} 12 |
13 | {% endblock content %} -------------------------------------------------------------------------------- /blogproject/templates/blog/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% load blog_extras %} 3 | 4 | {% block header %} 5 | {% with show_trigger=True %} 6 | {{ block.super }} 7 | {% endwith %} 8 | {% endblock header %} 9 | 10 | {% block main %} 11 | {% include 'blog/inclusions/_detail.html' %} 12 | {% endblock main %} 13 | 14 | {% block side %} 15 | {% include 'blog/inclusions/_toc.html' %} 16 | {{ block.super }} 17 | {% endblock side %} 18 | 19 | {% block sidebar_mobile %} 20 | {% include 'blog/inclusions/_sidebar_mobile.html' %} 21 | {% endblock sidebar_mobile %} -------------------------------------------------------------------------------- /blogproject/templates/comments/email/comment.html: -------------------------------------------------------------------------------- 1 | {% extends 'comments/email/base.html' %} 2 | {% block content %} 3 |4 | {{ comment.user.name }} 在 {{ content_object.title }} 中发布了评论: 5 |
6 |{{ comment.comment_html | safe }}
7 | 8 |如果点击无效,请复制以下链接到浏览器打开:
{{ link }}
11 | 发自:{{ site.name }} 12 |
13 | {% endblock content %} -------------------------------------------------------------------------------- /blogproject/webtools/views.py: -------------------------------------------------------------------------------- 1 | from braces.views import SetHeadlineMixin 2 | from django.views.generic import FormView 3 | 4 | from .forms import DjangoSecretKeyCreateForm 5 | 6 | 7 | class DjangoSecretKeyCreateView(SetHeadlineMixin, FormView): 8 | headline = "Django Secret Key 在线生成器" 9 | form_class = DjangoSecretKeyCreateForm 10 | template_name = "webtools/django_secret_key.html" 11 | 12 | def form_valid(self, form): 13 | return self.render_to_response( 14 | context={"form": form, "django_secret_key": form.create_secret_key()} 15 | ) 16 | -------------------------------------------------------------------------------- /blogproject/templates/blog/inclusions/_related.html: -------------------------------------------------------------------------------- 1 | {% load more_like_this %} 2 | 3 |17 | -- EOF -- 18 |
19 | 20 |
13 |
19 | 16 | -- EOF -- 17 |
18 | {% include 'inclusions/_donate.html' %} 19 | {% include 'blog/inclusions/_tags.html' %} 20 | 21 | {% block related_posts %}{% endblock related_posts %} 22 |{% highlight result.object.body with query %}
29 |{{ entry.brief }}
{% endif %} 29 | 30 |