aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar ks129 <[email protected]>2020-10-04 18:55:33 +0300
committerGravatar ks129 <[email protected]>2020-10-04 18:55:33 +0300
commitaff3a89c3cec04eda096e8f27115e36108ee6286 (patch)
tree299fb51b60916e6b552fa1ac7e0e05dbef512343
parentAdd more information to how to write a guide guide (diff)
Change guides system to content system
As this system will be used for more than just guides, I had to do some refactoring to match this system with plans. Basically now there isn't guides, but articles instead.
-rw-r--r--pydis_site/apps/content/__init__.py (renamed from pydis_site/apps/guides/__init__.py)0
-rw-r--r--pydis_site/apps/content/apps.py7
-rw-r--r--pydis_site/apps/content/migrations/__init__.py (renamed from pydis_site/apps/guides/migrations/__init__.py)0
-rw-r--r--pydis_site/apps/content/resources/content/guides/_info.yml2
-rw-r--r--pydis_site/apps/content/resources/content/guides/how-to-write-a-guide.md (renamed from pydis_site/apps/guides/resources/guides/how-to-write-a-guide.md)0
-rw-r--r--pydis_site/apps/content/tests/__init__.py (renamed from pydis_site/apps/guides/tests/__init__.py)0
-rw-r--r--pydis_site/apps/content/tests/test_content/category/_info.yml (renamed from pydis_site/apps/guides/tests/test_guides/category/_info.yml)0
-rw-r--r--pydis_site/apps/content/tests/test_content/category/test3.md (renamed from pydis_site/apps/guides/tests/test_guides/category/test3.md)0
-rw-r--r--pydis_site/apps/content/tests/test_content/test.md (renamed from pydis_site/apps/guides/tests/test_guides/test.md)0
-rw-r--r--pydis_site/apps/content/tests/test_content/test2.md (renamed from pydis_site/apps/guides/tests/test_guides/test2.md)0
-rw-r--r--pydis_site/apps/content/tests/test_utils.py122
-rw-r--r--pydis_site/apps/content/tests/test_views.py104
-rw-r--r--pydis_site/apps/content/urls.py11
-rw-r--r--pydis_site/apps/content/utils.py (renamed from pydis_site/apps/guides/utils.py)26
-rw-r--r--pydis_site/apps/content/views/__init__.py5
-rw-r--r--pydis_site/apps/content/views/article.py (renamed from pydis_site/apps/guides/views/guide.py)22
-rw-r--r--pydis_site/apps/content/views/articles.py14
-rw-r--r--pydis_site/apps/content/views/category.py18
-rw-r--r--pydis_site/apps/guides/apps.py7
-rw-r--r--pydis_site/apps/guides/tests/test_utils.py122
-rw-r--r--pydis_site/apps/guides/tests/test_views.py104
-rw-r--r--pydis_site/apps/guides/urls.py11
-rw-r--r--pydis_site/apps/guides/views/__init__.py5
-rw-r--r--pydis_site/apps/guides/views/category.py18
-rw-r--r--pydis_site/apps/guides/views/guides.py14
-rw-r--r--pydis_site/apps/home/urls.py2
-rw-r--r--pydis_site/settings.py2
-rw-r--r--pydis_site/static/css/content/articles.css (renamed from pydis_site/static/css/guides/guide.css)0
-rw-r--r--pydis_site/templates/content/article.html (renamed from pydis_site/templates/guides/guide.html)18
-rw-r--r--pydis_site/templates/content/articles.html (renamed from pydis_site/templates/guides/guides.html)10
-rw-r--r--pydis_site/templates/content/category.html (renamed from pydis_site/templates/guides/category.html)8
31 files changed, 328 insertions, 324 deletions
diff --git a/pydis_site/apps/guides/__init__.py b/pydis_site/apps/content/__init__.py
index e69de29b..e69de29b 100644
--- a/pydis_site/apps/guides/__init__.py
+++ b/pydis_site/apps/content/__init__.py
diff --git a/pydis_site/apps/content/apps.py b/pydis_site/apps/content/apps.py
new file mode 100644
index 00000000..1e300a48
--- /dev/null
+++ b/pydis_site/apps/content/apps.py
@@ -0,0 +1,7 @@
+from django.apps import AppConfig
+
+
+class ContentConfig(AppConfig):
+ """Django AppConfig for content app."""
+
+ name = 'content'
diff --git a/pydis_site/apps/guides/migrations/__init__.py b/pydis_site/apps/content/migrations/__init__.py
index e69de29b..e69de29b 100644
--- a/pydis_site/apps/guides/migrations/__init__.py
+++ b/pydis_site/apps/content/migrations/__init__.py
diff --git a/pydis_site/apps/content/resources/content/guides/_info.yml b/pydis_site/apps/content/resources/content/guides/_info.yml
new file mode 100644
index 00000000..8a38271d
--- /dev/null
+++ b/pydis_site/apps/content/resources/content/guides/_info.yml
@@ -0,0 +1,2 @@
+name: Guides
+description: Python and PyDis guides. \ No newline at end of file
diff --git a/pydis_site/apps/guides/resources/guides/how-to-write-a-guide.md b/pydis_site/apps/content/resources/content/guides/how-to-write-a-guide.md
index 072c2538..072c2538 100644
--- a/pydis_site/apps/guides/resources/guides/how-to-write-a-guide.md
+++ b/pydis_site/apps/content/resources/content/guides/how-to-write-a-guide.md
diff --git a/pydis_site/apps/guides/tests/__init__.py b/pydis_site/apps/content/tests/__init__.py
index e69de29b..e69de29b 100644
--- a/pydis_site/apps/guides/tests/__init__.py
+++ b/pydis_site/apps/content/tests/__init__.py
diff --git a/pydis_site/apps/guides/tests/test_guides/category/_info.yml b/pydis_site/apps/content/tests/test_content/category/_info.yml
index 8311509d..8311509d 100644
--- a/pydis_site/apps/guides/tests/test_guides/category/_info.yml
+++ b/pydis_site/apps/content/tests/test_content/category/_info.yml
diff --git a/pydis_site/apps/guides/tests/test_guides/category/test3.md b/pydis_site/apps/content/tests/test_content/category/test3.md
index bdde6188..bdde6188 100644
--- a/pydis_site/apps/guides/tests/test_guides/category/test3.md
+++ b/pydis_site/apps/content/tests/test_content/category/test3.md
diff --git a/pydis_site/apps/guides/tests/test_guides/test.md b/pydis_site/apps/content/tests/test_content/test.md
index 7a917899..7a917899 100644
--- a/pydis_site/apps/guides/tests/test_guides/test.md
+++ b/pydis_site/apps/content/tests/test_content/test.md
diff --git a/pydis_site/apps/guides/tests/test_guides/test2.md b/pydis_site/apps/content/tests/test_content/test2.md
index f0852356..f0852356 100644
--- a/pydis_site/apps/guides/tests/test_guides/test2.md
+++ b/pydis_site/apps/content/tests/test_content/test2.md
diff --git a/pydis_site/apps/content/tests/test_utils.py b/pydis_site/apps/content/tests/test_utils.py
new file mode 100644
index 00000000..82e1ac5f
--- /dev/null
+++ b/pydis_site/apps/content/tests/test_utils.py
@@ -0,0 +1,122 @@
+import os
+from unittest.mock import patch
+
+from django.conf import settings
+from django.http import Http404
+from django.test import TestCase
+from markdown import Markdown
+
+from pydis_site.apps.content import utils
+
+BASE_PATH = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "tests", "test_content")
+
+
+class TestGetBasePath(TestCase):
+ def test_get_base_path(self):
+ """Test does function return content base path."""
+ self.assertEqual(
+ utils._get_base_path(),
+ os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content")
+ )
+
+
+class TestGetCategory(TestCase):
+ def test_get_category_successfully(self):
+ """Check does this get right data from category data file."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_category("category")
+
+ self.assertEqual(result, {"name": "My Category", "description": "My Description"})
+
+ def test_get_category_not_exists(self):
+ """Check does this raise 404 error when category don't exists."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ with self.assertRaises(Http404):
+ utils.get_category("invalid")
+
+ def test_get_category_not_directory(self):
+ """Check does this raise 404 error when category isn't directory."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ with self.assertRaises(Http404):
+ utils.get_category("test.md")
+
+
+class TestGetCategories(TestCase):
+ def test_get_categories(self):
+ """Check does this return test content categories."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_categories()
+
+ self.assertEqual(result, {"category": {"name": "My Category", "description": "My Description"}})
+
+
+class TestGetArticles(TestCase):
+ def test_get_all_root_articles(self):
+ """Check does this return all root level testing content."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_articles()
+
+ for case in ["test", "test2"]:
+ with self.subTest(guide=case):
+ md = Markdown(extensions=['meta'])
+ with open(os.path.join(BASE_PATH, f"{case}.md")) as f:
+ md.convert(f.read())
+
+ self.assertIn(case, result)
+ self.assertEqual(md.Meta, result[case])
+
+ def test_get_all_category_articles(self):
+ """Check does this return all category testing content."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_articles("category")
+
+ md = Markdown(extensions=['meta'])
+ with open(os.path.join(BASE_PATH, "category", "test3.md")) as f:
+ md.convert(f.read())
+
+ self.assertIn("test3", result)
+ self.assertEqual(md.Meta, result["test3"])
+
+
+class TestGetArticle(TestCase):
+ def test_get_root_article_success(self):
+ """Check does this return article HTML and metadata when root article exist."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_article("test", None)
+
+ md = Markdown(extensions=['meta', 'attr_list', 'fenced_code'])
+
+ with open(os.path.join(BASE_PATH, "test.md")) as f:
+ html = md.convert(f.read())
+
+ self.assertEqual(result, {"article": html, "metadata": md.Meta})
+
+ def test_get_root_article_dont_exist(self):
+ """Check does this raise Http404 when root article don't exist."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ with self.assertRaises(Http404):
+ utils.get_article("invalid", None)
+
+ def test_get_category_article_success(self):
+ """Check does this return article HTML and metadata when category guide exist."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ result = utils.get_article("test3", "category")
+
+ md = Markdown(extensions=['meta', 'attr_list', 'fenced_code'])
+
+ with open(os.path.join(BASE_PATH, "category", "test3.md")) as f:
+ html = md.convert(f.read())
+
+ self.assertEqual(result, {"article": html, "metadata": md.Meta})
+
+ def test_get_category_article_dont_exist(self):
+ """Check does this raise Http404 when category article don't exist."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ with self.assertRaises(Http404):
+ utils.get_article("invalid", "category")
+
+ def test_get_category_article_category_dont_exist(self):
+ """Check does this raise Http404 when category don't exist."""
+ with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH):
+ with self.assertRaises(Http404):
+ utils.get_article("some-guide", "invalid")
diff --git a/pydis_site/apps/content/tests/test_views.py b/pydis_site/apps/content/tests/test_views.py
new file mode 100644
index 00000000..98054534
--- /dev/null
+++ b/pydis_site/apps/content/tests/test_views.py
@@ -0,0 +1,104 @@
+from unittest.mock import patch
+
+from django.http import Http404
+from django.test import TestCase
+from django_hosts.resolvers import reverse
+
+
+class TestGuidesIndexView(TestCase):
+ @patch("pydis_site.apps.content.views.articles.get_articles")
+ @patch("pydis_site.apps.content.views.articles.get_categories")
+ def test_articles_index_return_200(self, get_categories_mock, get_articles_mock):
+ """Check that content index return HTTP code 200."""
+ get_categories_mock.return_value = {}
+ get_articles_mock.return_value = {}
+
+ url = reverse('content:content')
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ get_articles_mock.assert_called_once()
+ get_categories_mock.assert_called_once()
+
+
+class TestGuideView(TestCase):
+ @patch("pydis_site.apps.content.views.article.os.path.getmtime")
+ @patch("pydis_site.apps.content.views.article.get_article")
+ @patch("pydis_site.apps.content.views.article.get_category")
+ def test_guide_return_code_200(self, get_category_mock, get_article_mock, get_time_mock):
+ get_article_mock.return_value = {"guide": "test", "metadata": {}}
+
+ url = reverse("content:article", args=["test-guide"])
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ get_category_mock.assert_not_called()
+ get_article_mock.assert_called_once_with("test-guide", None)
+
+ @patch("pydis_site.apps.content.views.article.os.path.getmtime")
+ @patch("pydis_site.apps.content.views.article.get_article")
+ @patch("pydis_site.apps.content.views.article.get_category")
+ def test_guide_return_404(self, get_category_mock, get_article_mock, get_time_mock):
+ """Check that return code is 404 when invalid article provided."""
+ get_article_mock.side_effect = Http404("Article not found.")
+
+ url = reverse("content:article", args=["invalid-guide"])
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 404)
+ get_article_mock.assert_called_once_with("invalid-guide", None)
+ get_category_mock.assert_not_called()
+
+
+class TestCategoryView(TestCase):
+ @patch("pydis_site.apps.content.views.category.get_category")
+ @patch("pydis_site.apps.content.views.category.get_articles")
+ def test_valid_category_code_200(self, get_articles_mock, get_category_mock):
+ """Check that return code is 200 when visiting valid category."""
+ get_category_mock.return_value = {"name": "test", "description": "test"}
+ get_articles_mock.return_value = {}
+
+ url = reverse("content:category", args=["category"])
+ response = self.client.get(url)
+
+ self.assertEqual(response.status_code, 200)
+ get_articles_mock.assert_called_once_with("category")
+ get_category_mock.assert_called_once_with("category")
+
+ @patch("pydis_site.apps.content.views.category.get_category")
+ @patch("pydis_site.apps.content.views.category.get_articles")
+ def test_invalid_category_code_404(self, get_articles_mock, get_category_mock):
+ """Check that return code is 404 when trying to visit invalid category."""
+ get_category_mock.side_effect = Http404("Category not found.")
+
+ url = reverse("content:category", args=["invalid-category"])
+ response = self.client.get(url)
+
+ self.assertEqual(response.status_code, 404)
+ get_category_mock.assert_called_once_with("invalid-category")
+ get_articles_mock.assert_not_called()
+
+
+class TestCategoryGuidesView(TestCase):
+ @patch("pydis_site.apps.content.views.article.os.path.getmtime")
+ @patch("pydis_site.apps.content.views.article.get_article")
+ @patch("pydis_site.apps.content.views.article.get_category")
+ def test_valid_category_article_code_200(self, get_category_mock, get_article_mock, get_time_mock):
+ """Check that return code is 200 when visiting valid category article."""
+ get_article_mock.return_value = {"guide": "test", "metadata": {}}
+
+ url = reverse("content:category_article", args=["category", "test3"])
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ get_article_mock.assert_called_once_with("test3", "category")
+ get_category_mock.assert_called_once_with("category")
+
+ @patch("pydis_site.apps.content.views.article.os.path.getmtime")
+ @patch("pydis_site.apps.content.views.article.get_article")
+ @patch("pydis_site.apps.content.views.article.get_category")
+ def test_invalid_category_article_code_404(self, get_category_mock, get_article_mock, get_time_mock):
+ """Check that return code is 200 when trying to visit invalid category article."""
+ get_article_mock.side_effect = Http404("Article not found.")
+
+ url = reverse("content:category_article", args=["category", "invalid"])
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 404)
+ get_article_mock.assert_called_once_with("invalid", "category")
+ get_category_mock.assert_not_called()
diff --git a/pydis_site/apps/content/urls.py b/pydis_site/apps/content/urls.py
new file mode 100644
index 00000000..ae9b1e57
--- /dev/null
+++ b/pydis_site/apps/content/urls.py
@@ -0,0 +1,11 @@
+from django.urls import path
+
+from . import views
+
+app_name = "content"
+urlpatterns = [
+ path("", views.ArticlesView.as_view(), name='content'),
+ path("category/<str:category>/", views.CategoryView.as_view(), name='category'),
+ path("category/<str:category>/<str:article>/", views.ArticleView.as_view(), name='category_article'),
+ path("<str:article>/", views.ArticleView.as_view(), name='article')
+]
diff --git a/pydis_site/apps/guides/utils.py b/pydis_site/apps/content/utils.py
index c6f668f7..57905a69 100644
--- a/pydis_site/apps/guides/utils.py
+++ b/pydis_site/apps/content/utils.py
@@ -9,7 +9,7 @@ from markdown import Markdown
def _get_base_path() -> str:
"""Have extra function for base path getting for testability."""
- return os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides")
+ return os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content")
def get_category(category: str) -> Dict[str, str]:
@@ -34,14 +34,14 @@ def get_categories() -> Dict[str, Dict]:
return categories
-def get_guides(category: Optional[str] = None) -> Dict[str, Dict]:
- """Get all root guides when category is not specified. Otherwise get all this category guides."""
+def get_articles(category: Optional[str] = None) -> Dict[str, Dict]:
+ """Get all root content when category is not specified. Otherwise get all this category content."""
if category is None:
base_dir = _get_base_path()
else:
base_dir = os.path.join(_get_base_path(), category)
- guides = {}
+ articles = {}
for filename in os.listdir(base_dir):
full_path = os.path.join(base_dir, filename)
@@ -50,13 +50,13 @@ def get_guides(category: Optional[str] = None) -> Dict[str, Dict]:
with open(full_path) as f:
md.convert(f.read())
- guides[os.path.splitext(filename)[0]] = md.Meta
+ articles[os.path.splitext(filename)[0]] = md.Meta
- return guides
+ return articles
-def get_guide(guide: str, category: Optional[str]) -> Dict[str, Union[str, Dict]]:
- """Get one specific guide. When category is specified, get it from there."""
+def get_article(article: str, category: Optional[str]) -> Dict[str, Union[str, Dict]]:
+ """Get one specific article. When category is specified, get it from there."""
if category is None:
base_path = _get_base_path()
else:
@@ -65,13 +65,13 @@ def get_guide(guide: str, category: Optional[str]) -> Dict[str, Union[str, Dict]
if not os.path.exists(base_path) or not os.path.isdir(base_path):
raise Http404("Category not found.")
- guide_path = os.path.join(base_path, f"{guide}.md")
- if not os.path.exists(guide_path) or not os.path.isfile(guide_path):
- raise Http404("Guide not found.")
+ article_path = os.path.join(base_path, f"{article}.md")
+ if not os.path.exists(article_path) or not os.path.isfile(article_path):
+ raise Http404("Article not found.")
md = Markdown(extensions=['meta', 'attr_list', 'fenced_code'])
- with open(guide_path) as f:
+ with open(article_path) as f:
html = md.convert(f.read())
- return {"guide": html, "metadata": md.Meta}
+ return {"article": html, "metadata": md.Meta}
diff --git a/pydis_site/apps/content/views/__init__.py b/pydis_site/apps/content/views/__init__.py
new file mode 100644
index 00000000..b50d487b
--- /dev/null
+++ b/pydis_site/apps/content/views/__init__.py
@@ -0,0 +1,5 @@
+from .category import CategoryView
+from .article import ArticleView
+from .articles import ArticlesView
+
+__all__ = ["ArticleView", "ArticlesView", "CategoryView"]
diff --git a/pydis_site/apps/guides/views/guide.py b/pydis_site/apps/content/views/article.py
index bcd68bc4..b34ca3ee 100644
--- a/pydis_site/apps/guides/views/guide.py
+++ b/pydis_site/apps/content/views/article.py
@@ -8,22 +8,24 @@ from django.http import HttpResponse
from django.shortcuts import render
from django.views import View
-from pydis_site.apps.guides.utils import get_category, get_guide
+from pydis_site.apps.content.utils import get_category, get_article
-class GuideView(View):
+class ArticleView(View):
"""Shows specific guide page."""
- def get(self, request: WSGIRequest, guide: str, category: Optional[str] = None) -> HttpResponse:
+ def get(self, request: WSGIRequest, article: str, category: Optional[str] = None) -> HttpResponse:
"""Collect guide content and display it. When guide don't exist, return 404."""
- guide_result = get_guide(guide, category)
+ article_result = get_article(article, category)
if category is not None:
path = os.path.join(
- settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides", category, f"{guide}.md"
+ settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content", category, f"{article}.md"
)
else:
- path = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides", f"{guide}.md")
+ path = os.path.join(
+ settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content", f"{article}.md"
+ )
if category is not None:
category_data = get_category(category)
@@ -33,15 +35,15 @@ class GuideView(View):
return render(
request,
- "guides/guide.html",
+ "content/article.html",
{
- "guide": guide_result,
+ "article": article_result,
"last_modified": datetime.fromtimestamp(os.path.getmtime(path)).strftime("%dth %B %Y"),
"category_data": category_data,
"relevant_links": {
link: value for link, value in zip(
- guide_result["metadata"].get("relevantlinks", []),
- guide_result["metadata"].get("relevantlinkvalues", [])
+ article_result["metadata"].get("relevantlinks", []),
+ article_result["metadata"].get("relevantlinkvalues", [])
)
}
}
diff --git a/pydis_site/apps/content/views/articles.py b/pydis_site/apps/content/views/articles.py
new file mode 100644
index 00000000..ff945a19
--- /dev/null
+++ b/pydis_site/apps/content/views/articles.py
@@ -0,0 +1,14 @@
+from django.core.handlers.wsgi import WSGIRequest
+from django.http import HttpResponse
+from django.shortcuts import render
+from django.views import View
+
+from pydis_site.apps.content.utils import get_categories, get_articles
+
+
+class ArticlesView(View):
+ """Shows all content and categories."""
+
+ def get(self, request: WSGIRequest) -> HttpResponse:
+ """Shows all content and categories."""
+ return render(request, "content/articles.html", {"content": get_articles(), "categories": get_categories()})
diff --git a/pydis_site/apps/content/views/category.py b/pydis_site/apps/content/views/category.py
new file mode 100644
index 00000000..62e80a47
--- /dev/null
+++ b/pydis_site/apps/content/views/category.py
@@ -0,0 +1,18 @@
+from django.core.handlers.wsgi import WSGIRequest
+from django.http import HttpResponse
+from django.shortcuts import render
+from django.views import View
+
+from pydis_site.apps.content.utils import get_category, get_articles
+
+
+class CategoryView(View):
+ """Handles content category page."""
+
+ def get(self, request: WSGIRequest, category: str) -> HttpResponse:
+ """Handles page that displays category content."""
+ return render(
+ request,
+ "content/category.html",
+ {"category_info": get_category(category), "content": get_articles(category), "category_name": category}
+ )
diff --git a/pydis_site/apps/guides/apps.py b/pydis_site/apps/guides/apps.py
deleted file mode 100644
index 8dfa4f65..00000000
--- a/pydis_site/apps/guides/apps.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from django.apps import AppConfig
-
-
-class GuidesConfig(AppConfig):
- """Django AppConfig for guides app."""
-
- name = 'guides'
diff --git a/pydis_site/apps/guides/tests/test_utils.py b/pydis_site/apps/guides/tests/test_utils.py
deleted file mode 100644
index e7448be6..00000000
--- a/pydis_site/apps/guides/tests/test_utils.py
+++ /dev/null
@@ -1,122 +0,0 @@
-import os
-from unittest.mock import patch
-
-from django.conf import settings
-from django.http import Http404
-from django.test import TestCase
-from markdown import Markdown
-
-from pydis_site.apps.guides import utils
-
-BASE_PATH = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "tests", "test_guides")
-
-
-class TestGetBasePath(TestCase):
- def test_get_base_path(self):
- """Test does function return guides base path."""
- self.assertEqual(
- utils._get_base_path(),
- os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides")
- )
-
-
-class TestGetCategory(TestCase):
- def test_get_category_successfully(self):
- """Check does this get right data from category data file."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_category("category")
-
- self.assertEqual(result, {"name": "My Category", "description": "My Description"})
-
- def test_get_category_not_exists(self):
- """Check does this raise 404 error when category don't exists."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- with self.assertRaises(Http404):
- utils.get_category("invalid")
-
- def test_get_category_not_directory(self):
- """Check does this raise 404 error when category isn't directory."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- with self.assertRaises(Http404):
- utils.get_category("test.md")
-
-
-class TestGetCategories(TestCase):
- def test_get_categories(self):
- """Check does this return test guides categories."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_categories()
-
- self.assertEqual(result, {"category": {"name": "My Category", "description": "My Description"}})
-
-
-class TestGetGuides(TestCase):
- def test_get_all_root_guides(self):
- """Check does this return all root level testing guides."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_guides()
-
- for case in ["test", "test2"]:
- with self.subTest(guide=case):
- md = Markdown(extensions=['meta'])
- with open(os.path.join(BASE_PATH, f"{case}.md")) as f:
- md.convert(f.read())
-
- self.assertIn(case, result)
- self.assertEqual(md.Meta, result[case])
-
- def test_get_all_category_guides(self):
- """Check does this return all category testing guides."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_guides("category")
-
- md = Markdown(extensions=['meta'])
- with open(os.path.join(BASE_PATH, "category", "test3.md")) as f:
- md.convert(f.read())
-
- self.assertIn("test3", result)
- self.assertEqual(md.Meta, result["test3"])
-
-
-class TestGetGuide(TestCase):
- def test_get_root_guide_success(self):
- """Check does this return guide HTML and metadata when root guide exist."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_guide("test", None)
-
- md = Markdown(extensions=['meta', 'attr_list', 'fenced_code'])
-
- with open(os.path.join(BASE_PATH, "test.md")) as f:
- html = md.convert(f.read())
-
- self.assertEqual(result, {"guide": html, "metadata": md.Meta})
-
- def test_get_root_guide_dont_exist(self):
- """Check does this raise Http404 when root guide don't exist."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- with self.assertRaises(Http404):
- result = utils.get_guide("invalid", None)
-
- def test_get_category_guide_success(self):
- """Check does this return guide HTML and metadata when category guide exist."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- result = utils.get_guide("test3", "category")
-
- md = Markdown(extensions=['meta', 'attr_list', 'fenced_code'])
-
- with open(os.path.join(BASE_PATH, "category", "test3.md")) as f:
- html = md.convert(f.read())
-
- self.assertEqual(result, {"guide": html, "metadata": md.Meta})
-
- def test_get_category_guide_dont_exist(self):
- """Check does this raise Http404 when category guide don't exist."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- with self.assertRaises(Http404):
- result = utils.get_guide("invalid", "category")
-
- def test_get_category_guide_category_dont_exist(self):
- """Check does this raise Http404 when category don't exist."""
- with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH):
- with self.assertRaises(Http404):
- result = utils.get_guide("some-guide", "invalid")
diff --git a/pydis_site/apps/guides/tests/test_views.py b/pydis_site/apps/guides/tests/test_views.py
deleted file mode 100644
index e3945136..00000000
--- a/pydis_site/apps/guides/tests/test_views.py
+++ /dev/null
@@ -1,104 +0,0 @@
-from unittest.mock import patch
-
-from django.http import Http404
-from django.test import TestCase
-from django_hosts.resolvers import reverse
-
-
-class TestGuidesIndexView(TestCase):
- @patch("pydis_site.apps.guides.views.guides.get_guides")
- @patch("pydis_site.apps.guides.views.guides.get_categories")
- def test_guides_index_return_200(self, get_categories_mock, get_guides_mock):
- """Check that guides index return HTTP code 200."""
- get_categories_mock.return_value = {}
- get_guides_mock.return_value = {}
-
- url = reverse('guide:guides')
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
- get_guides_mock.assert_called_once()
- get_categories_mock.assert_called_once()
-
-
-class TestGuideView(TestCase):
- @patch("pydis_site.apps.guides.views.guide.os.path.getmtime")
- @patch("pydis_site.apps.guides.views.guide.get_guide")
- @patch("pydis_site.apps.guides.views.guide.get_category")
- def test_guide_return_code_200(self, get_category_mock, get_guide_mock, get_time_mock):
- get_guide_mock.return_value = {"guide": "test", "metadata": {}}
-
- url = reverse("guide:guide", args=["test-guide"])
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
- get_category_mock.assert_not_called()
- get_guide_mock.assert_called_once_with("test-guide", None)
-
- @patch("pydis_site.apps.guides.views.guide.os.path.getmtime")
- @patch("pydis_site.apps.guides.views.guide.get_guide")
- @patch("pydis_site.apps.guides.views.guide.get_category")
- def test_guide_return_404(self, get_category_mock, get_guide_mock, get_time_mock):
- """Check that return code is 404 when invalid guide provided."""
- get_guide_mock.side_effect = Http404("Guide not found.")
-
- url = reverse("guide:guide", args=["invalid-guide"])
- response = self.client.get(url)
- self.assertEqual(response.status_code, 404)
- get_guide_mock.assert_called_once_with("invalid-guide", None)
- get_category_mock.assert_not_called()
-
-
-class TestCategoryView(TestCase):
- @patch("pydis_site.apps.guides.views.category.get_category")
- @patch("pydis_site.apps.guides.views.category.get_guides")
- def test_valid_category_code_200(self, get_guides_mock, get_category_mock):
- """Check that return code is 200 when visiting valid category."""
- get_category_mock.return_value = {"name": "test", "description": "test"}
- get_guides_mock.return_value = {}
-
- url = reverse("guide:category", args=["category"])
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 200)
- get_guides_mock.assert_called_once_with("category")
- get_category_mock.assert_called_once_with("category")
-
- @patch("pydis_site.apps.guides.views.category.get_category")
- @patch("pydis_site.apps.guides.views.category.get_guides")
- def test_invalid_category_code_404(self, get_guides_mock, get_category_mock):
- """Check that return code is 404 when trying to visit invalid category."""
- get_category_mock.side_effect = Http404("Category not found.")
-
- url = reverse("guide:category", args=["invalid-category"])
- response = self.client.get(url)
-
- self.assertEqual(response.status_code, 404)
- get_category_mock.assert_called_once_with("invalid-category")
- get_guides_mock.assert_not_called()
-
-
-class TestCategoryGuidesView(TestCase):
- @patch("pydis_site.apps.guides.views.guide.os.path.getmtime")
- @patch("pydis_site.apps.guides.views.guide.get_guide")
- @patch("pydis_site.apps.guides.views.guide.get_category")
- def test_valid_category_guide_code_200(self, get_category_mock, get_guide_mock, get_time_mock):
- """Check that return code is 200 when visiting valid category article."""
- get_guide_mock.return_value = {"guide": "test", "metadata": {}}
-
- url = reverse("guide:category_guide", args=["category", "test3"])
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
- get_guide_mock.assert_called_once_with("test3", "category")
- get_category_mock.assert_called_once_with("category")
-
- @patch("pydis_site.apps.guides.views.guide.os.path.getmtime")
- @patch("pydis_site.apps.guides.views.guide.get_guide")
- @patch("pydis_site.apps.guides.views.guide.get_category")
- def test_invalid_category_guide_code_404(self, get_category_mock, get_guide_mock, get_time_mock):
- """Check that return code is 200 when trying to visit invalid category article."""
- get_guide_mock.side_effect = Http404("Guide not found.")
-
- url = reverse("guide:category_guide", args=["category", "invalid"])
- response = self.client.get(url)
- self.assertEqual(response.status_code, 404)
- get_guide_mock.assert_called_once_with("invalid", "category")
- get_category_mock.assert_not_called()
diff --git a/pydis_site/apps/guides/urls.py b/pydis_site/apps/guides/urls.py
deleted file mode 100644
index 69641638..00000000
--- a/pydis_site/apps/guides/urls.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.urls import path
-
-from . import views
-
-app_name = "guides"
-urlpatterns = [
- path("", views.GuidesView.as_view(), name='guides'),
- path("category/<str:category>/", views.CategoryView.as_view(), name='category'),
- path("category/<str:category>/<str:guide>/", views.GuideView.as_view(), name='category_guide'),
- path("<str:guide>/", views.GuideView.as_view(), name='guide')
-]
diff --git a/pydis_site/apps/guides/views/__init__.py b/pydis_site/apps/guides/views/__init__.py
deleted file mode 100644
index 17a244c1..00000000
--- a/pydis_site/apps/guides/views/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from .category import CategoryView
-from .guide import GuideView
-from .guides import GuidesView
-
-__all__ = ["GuideView", "GuidesView", "CategoryView"]
diff --git a/pydis_site/apps/guides/views/category.py b/pydis_site/apps/guides/views/category.py
deleted file mode 100644
index 33e8c97b..00000000
--- a/pydis_site/apps/guides/views/category.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from django.core.handlers.wsgi import WSGIRequest
-from django.http import HttpResponse
-from django.shortcuts import render
-from django.views import View
-
-from pydis_site.apps.guides.utils import get_category, get_guides
-
-
-class CategoryView(View):
- """Handles guides category page."""
-
- def get(self, request: WSGIRequest, category: str) -> HttpResponse:
- """Handles page that displays category guides."""
- return render(
- request,
- "guides/category.html",
- {"category_info": get_category(category), "guides": get_guides(category), "category_name": category}
- )
diff --git a/pydis_site/apps/guides/views/guides.py b/pydis_site/apps/guides/views/guides.py
deleted file mode 100644
index bb8b565e..00000000
--- a/pydis_site/apps/guides/views/guides.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.core.handlers.wsgi import WSGIRequest
-from django.http import HttpResponse
-from django.shortcuts import render
-from django.views import View
-
-from pydis_site.apps.guides.utils import get_categories, get_guides
-
-
-class GuidesView(View):
- """Shows all guides and categories."""
-
- def get(self, request: WSGIRequest) -> HttpResponse:
- """Shows all guides and categories."""
- return render(request, "guides/guides.html", {"guides": get_guides(), "categories": get_categories()})
diff --git a/pydis_site/apps/home/urls.py b/pydis_site/apps/home/urls.py
index 06d62352..e49fd4e0 100644
--- a/pydis_site/apps/home/urls.py
+++ b/pydis_site/apps/home/urls.py
@@ -39,5 +39,5 @@ urlpatterns = [
path('admin/', admin.site.urls),
path('notifications/', include('django_nyt.urls')),
- path('guides/', include('pydis_site.apps.guides.urls', namespace='guide')),
+ path('content/', include('pydis_site.apps.content.urls', namespace='content')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/pydis_site/settings.py b/pydis_site/settings.py
index 6aff0fc1..aaac3bfe 100644
--- a/pydis_site/settings.py
+++ b/pydis_site/settings.py
@@ -91,7 +91,7 @@ INSTALLED_APPS = [
'pydis_site.apps.api',
'pydis_site.apps.home',
'pydis_site.apps.staff',
- 'pydis_site.apps.guides',
+ 'pydis_site.apps.content',
'django.contrib.admin',
'django.contrib.auth',
diff --git a/pydis_site/static/css/guides/guide.css b/pydis_site/static/css/content/articles.css
index fa7a0ba5..fa7a0ba5 100644
--- a/pydis_site/static/css/guides/guide.css
+++ b/pydis_site/static/css/content/articles.css
diff --git a/pydis_site/templates/guides/guide.html b/pydis_site/templates/content/article.html
index 97fc8262..de6cd28d 100644
--- a/pydis_site/templates/guides/guide.html
+++ b/pydis_site/templates/content/article.html
@@ -3,10 +3,10 @@
{% block title %}{{ metadata.title|first }}{% endblock %}
{% block head %}
- <meta property="og:title" content="Python Discord - {{ guide.metadata.title|first }}" />
+ <meta property="og:title" content="Python Discord - {{ article.metadata.title|first }}" />
<meta property="og:type" content="website" />
- <meta property="og:description" content="{{ guide.metadata.shortdescription|first }}" />
- <link rel="stylesheet" href="{% static "css/guides/guide.css" %}">
+ <meta property="og:description" content="{{ article.metadata.shortdescription|first }}" />
+ <link rel="stylesheet" href="{% static "css/content/articles.css" %}">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
@@ -19,11 +19,11 @@
<div class="container">
<nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs">
<ul>
- <li><a href="/guides">Guides</a></li>
+ <li><a href="/content">Pages</a></li>
{% if category_data.raw_name is not None %}
- <li><a href="/guides/category/{{ category_data.raw_name }}">{{ category_data.name }}</a></li>
+ <li><a href="/content/category/{{ category_data.raw_name }}">{{ category_data.name }}</a></li>
{% endif %}
- <li class="is-active"><a href="#">{{ guide.metadata.title|first }}</a></li>
+ <li class="is-active"><a href="#">{{ article.metadata.title|first }}</a></li>
</ul>
</nav>
</div>
@@ -32,13 +32,13 @@
<section class="section">
<div class="content">
<div class="container">
- <h1 class="title">{{ guide.metadata.title|first }}</h1>
+ <h1 class="title">{{ article.metadata.title|first }}</h1>
<div class="columns is-variable is-8">
<div class="column is-two-thirds">
- {{ guide.guide|safe }}
+ {{ article.article|safe }}
<p class="has-text-weight-light is-size-7">
<strong>Last modified:</strong> {{ last_modified }}<br/>
- <strong>Contributors:</strong> {{ guide.metadata.contributors|join:", " }}
+ <strong>Contributors:</strong> {{ article.metadata.contributors|join:", " }}
</p>
</div>
<div class="column">
diff --git a/pydis_site/templates/guides/guides.html b/pydis_site/templates/content/articles.html
index 0e6f2073..6fea66e5 100644
--- a/pydis_site/templates/guides/guides.html
+++ b/pydis_site/templates/content/articles.html
@@ -3,7 +3,7 @@
{% block title %}Guides{% endblock %}
{% block head %}
- <link rel="stylesheet" href="{% static "css/guides/guide.css" %}">
+ <link rel="stylesheet" href="{% static "css/content/articles.css" %}">
{% endblock %}
{% block content %}
@@ -13,7 +13,7 @@
<div class="container">
<nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs">
<ul>
- <li class="is-active"><a href="/guides">Guides</a></li>
+ <li class="is-active"><a href="/content">Pages</a></li>
</ul>
</nav>
</div>
@@ -22,13 +22,13 @@
<section class="section">
<div class="container">
<div class="content">
- <h1>Guides</h1>
- {% for guide, data in guides.items %}
+ <h1>Articles</h1>
+ {% for article, data in content.items %}
<div class="box" style="max-width: 800px;">
<span class="icon is-size-4 is-medium">
<i class="fab fa-python is-size-3 is-black has-icon-padding" aria-hidden="true"></i>
</span>
- <a href="{{ guide }}/">
+ <a href="{{ article }}/">
<span class="is-size-4 has-text-weight-bold">{{ data.title.0 }}</span>
</a>
<p class="is-italic">{{ data.shortdescription.0 }}</p>
diff --git a/pydis_site/templates/guides/category.html b/pydis_site/templates/content/category.html
index f3a8c2ce..61e20c43 100644
--- a/pydis_site/templates/guides/category.html
+++ b/pydis_site/templates/content/category.html
@@ -6,7 +6,7 @@
<meta property="og:title" content="Python Discord - {{ category_info.name }}" />
<meta property="og:type" content="website" />
<meta property="og:description" content="{{ category_info.description }}" />
- <link rel="stylesheet" href="{% static "css/guides/guide.css" %}">
+ <link rel="stylesheet" href="{% static "css/content/articles.css" %}">
{% endblock %}
{% block content %}
@@ -16,7 +16,7 @@
<div class="container">
<nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs">
<ul>
- <li><a href="/guides">Guides</a></li>
+ <li><a href="/content">Pages</a></li>
<li class="is-active"><a href="#">{{ category_info.name }}</a></li>
</ul>
</nav>
@@ -27,12 +27,12 @@
<div class="container">
<div class="content">
<h1>{{ category_info.name }}</h1>
- {% for guide, data in guides.items %}
+ {% for article, data in content.items %}
<div class="box" style="max-width: 800px;">
<span class="icon is-size-4 is-medium">
<i class="fab fa-python is-size-3 is-black has-icon-padding" aria-hidden="true"></i>
</span>
- <a href="/guides/category/{{ category_name }}/{{ guide }}/">
+ <a href="/content/category/{{ category_name }}/{{ article }}/">
<span class="is-size-4 has-text-weight-bold">{{ data.title.0 }}</span>
</a>
<p class="is-italic">{{ data.shortdescription.0 }}</p>