aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2018-03-04 16:33:01 +0000
committerGravatar GitHub <[email protected]>2018-03-04 16:33:01 +0000
commit5099ae7055b313d1a93d53069c2cfbb0ca0dcf5a (patch)
treee8d4b781a38b17502f24e1fd9f444926e88544d6
parentFix navbar dropdown (diff)
Info pages #13xan #13xak (#36)
* Info pages and templates * Info pages and templates * Info pages and templates * Update navigation and fix up HTML * Navigation HTML spacing for readability * Fix error views not using `self.render()` * `render()` method should accept Any for context values * Change header linking CSS to a dedicated class * Rules page * Basic resources page setup * Fix headers for new CSS class * Resource categories and initial resource data * Add link to JSON file on GH - won't work until the branch is merged * Remove info overview page and redirect info root url to resources * Flake8 * Add some tests * Line lengths
-rw-r--r--app_test.py21
-rw-r--r--pysite/base_route.py4
-rw-r--r--pysite/views/error_handlers/http_4xx.py24
-rw-r--r--pysite/views/error_handlers/http_5xx.py39
-rw-r--r--pysite/views/main/info/index.py12
-rw-r--r--pysite/views/main/info/resources.py21
-rw-r--r--pysite/views/main/info/rules.py10
-rw-r--r--static/resources.json45
-rw-r--r--static/style.css8
-rw-r--r--templates/main/info/help.html10
-rw-r--r--templates/main/info/resources.html56
-rw-r--r--templates/main/info/rules.html116
-rw-r--r--templates/main/navigation.html42
13 files changed, 351 insertions, 57 deletions
diff --git a/app_test.py b/app_test.py
index 2e8a53fb..39c61ff5 100644
--- a/app_test.py
+++ b/app_test.py
@@ -33,11 +33,32 @@ class BaseEndpoints(SiteTest):
response = self.client.get('/', 'http://pytest.local')
self.assertEqual(response.status_code, 200)
+ def test_info_index(self):
+ """ Check the info index path responds with a 301 """
+ response = self.client.get('/info')
+ self.assertEqual(response.status_code, 301)
+
def test_info_help(self):
""" Check the info help path responds with 200 OK """
response = self.client.get('/info/help')
self.assertEqual(response.status_code, 200)
+ def test_info_resources(self):
+ """ Check the info resources path responds with 200 OK """
+ response = self.client.get('/info/resources')
+ self.assertEqual(response.status_code, 200)
+
+ def test_info_resources_json(self):
+ """ Check the resources JSON loads correctly """
+ response = self.client.get('/static/resources.json')
+ self.assertEqual(response.status_code, 200)
+ self.assertIsInstance(json.loads(response.data), dict)
+
+ def test_info_rules(self):
+ """ Check the info rules path responds with 200 OK """
+ response = self.client.get('/info/help')
+ self.assertEqual(response.status_code, 200)
+
def test_not_found(self):
""" Check paths without handlers returns 404 Not Found """
response = self.client.get('/nonexistentpath')
diff --git a/pysite/base_route.py b/pysite/base_route.py
index 400a4649..f389b56e 100644
--- a/pysite/base_route.py
+++ b/pysite/base_route.py
@@ -1,6 +1,6 @@
# coding=utf-8
from collections import Iterable
-from typing import Any, Dict
+from typing import Any
from flask import Blueprint, Response, jsonify, render_template
from flask.views import MethodView
@@ -17,7 +17,7 @@ class BaseView(MethodView):
name = None # type: str
- def render(self, *template_names: str, **context: Dict[str, Any]) -> str:
+ def render(self, *template_names: str, **context: Any) -> str:
"""
Render some templates and get them back in a form that you can simply return from your view function.
diff --git a/pysite/views/error_handlers/http_4xx.py b/pysite/views/error_handlers/http_4xx.py
index 5717feae..74d43d6c 100644
--- a/pysite/views/error_handlers/http_4xx.py
+++ b/pysite/views/error_handlers/http_4xx.py
@@ -1,5 +1,5 @@
# coding=utf-8
-from flask import render_template, request
+from flask import request
from werkzeug.exceptions import HTTPException
from pysite.base_route import ErrorView
@@ -13,17 +13,19 @@ class Error400View(ErrorView):
def get(self, error: HTTPException):
error_desc = ERROR_DESCRIPTIONS.get(error.code, "We're not really sure what happened there, please try again.")
- return render_template("errors/error.html", code=error.code, req=request, error_title=error_desc,
- error_message=error_desc +
- " If you believe we have made a mistake, please "
- "<a href='https://github.com"
- "/discord-python/site/issues'>open an issue on our GitHub</a>."), error.code
+ return self.render(
+ "errors/error.html", code=error.code, req=request, error_title=error_desc,
+ error_message=error_desc +
+ " If you believe we have made a mistake, please "
+ "<a href='https://github.com/discord-python/site/issues'>open an issue on our GitHub</a>."
+ ), error.code
def post(self, error: HTTPException):
error_desc = ERROR_DESCRIPTIONS.get(error.code, "We're not really sure what happened there, please try again.")
- return render_template("errors/error.html", code=error.code, req=request, error_title=error_desc,
- error_message=error_desc +
- " If you believe we have made a mistake, please "
- "<a href='https://github.com"
- "/discord-python/site/issues'>open an issue on our GitHub</a>."), error.code
+ return self.render(
+ "errors/error.html", code=error.code, req=request, error_title=error_desc,
+ error_message=error_desc +
+ " If you believe we have made a mistake, please "
+ "<a href='https://github.com/discord-python/site/issues'>open an issue on our GitHub</a>."
+ ), error.code
diff --git a/pysite/views/error_handlers/http_5xx.py b/pysite/views/error_handlers/http_5xx.py
index 6bbc8275..60d3b1bb 100644
--- a/pysite/views/error_handlers/http_5xx.py
+++ b/pysite/views/error_handlers/http_5xx.py
@@ -1,5 +1,5 @@
# coding=utf-8
-from flask import render_template, request
+from flask import request
from werkzeug.exceptions import HTTPException
from pysite.base_route import ErrorView
@@ -13,28 +13,21 @@ class Error500View(ErrorView):
def get(self, error: HTTPException):
error_desc = ERROR_DESCRIPTIONS.get(error.code, "We're not really sure what happened there, please try again.")
- return render_template("errors/error.html", code=error.code, req=request, error_title=error_desc,
- error_message="An error occurred while "
- "processing this "
- "request, please try "
- "again later. "
- "If you believe we have made a mistake, "
- "please "
- "<a href='https://github.com"
- "/discord-python/site/issues'>file an issue on our GitHub"
- "</a>."), error.code
+ return self.render(
+ "errors/error.html", code=error.code, req=request, error_title=error_desc,
+ error_message="An error occurred while processing this request, please try "
+ "again later. If you believe we have made a mistake, please "
+ "<a href='https://github.com/discord-python/site/issues'>file an issue on our"
+ " GitHub</a>."
+ ), error.code
def post(self, error: HTTPException):
- error_desc = ERROR_DESCRIPTIONS.get(error.code,
- "We're not really sure what happened there, please try again.")
+ error_desc = ERROR_DESCRIPTIONS.get(error.code, "We're not really sure what happened there, please try again.")
- return render_template("errors/error.html", code=error.code, req=request, error_title=error_desc,
- error_message="An error occurred while "
- "processing this "
- "request, please try "
- "again later. "
- "If you believe we have made a mistake, "
- "please "
- "<a href='https://github.com"
- "/discord-python/site/issues'>file an issue on our GitHub"
- "</a>."), error.code
+ return self.render(
+ "errors/error.html", code=error.code, req=request, error_title=error_desc,
+ error_message="An error occurred while processing this request, please try "
+ "again later. If you believe we have made a mistake, please "
+ "<a href='https://github.com/discord-python/site/issues'>file an issue on our"
+ " GitHub</a>."
+ ), error.code
diff --git a/pysite/views/main/info/index.py b/pysite/views/main/info/index.py
new file mode 100644
index 00000000..371a5353
--- /dev/null
+++ b/pysite/views/main/info/index.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+from flask import redirect
+
+from pysite.base_route import RouteView
+
+
+class IndexView(RouteView):
+ path = "/info/"
+ name = "info"
+
+ def get(self):
+ return redirect("/info/resources")
diff --git a/pysite/views/main/info/resources.py b/pysite/views/main/info/resources.py
new file mode 100644
index 00000000..bce162f4
--- /dev/null
+++ b/pysite/views/main/info/resources.py
@@ -0,0 +1,21 @@
+# coding=utf-8
+import json
+from logging import getLogger
+
+from pysite.base_route import RouteView
+
+
+try:
+ with open("static/resources.json") as fh:
+ categories = json.load(fh)
+except Exception:
+ getLogger("Resources").exception("Failed to load resources.json")
+ categories = None
+
+
+class ResourcesView(RouteView):
+ path = "/info/resources"
+ name = "info/resources"
+
+ def get(self):
+ return self.render("main/info/resources.html", categories=categories)
diff --git a/pysite/views/main/info/rules.py b/pysite/views/main/info/rules.py
new file mode 100644
index 00000000..75faded1
--- /dev/null
+++ b/pysite/views/main/info/rules.py
@@ -0,0 +1,10 @@
+# coding=utf-8
+from pysite.base_route import RouteView
+
+
+class RulesView(RouteView):
+ path = "/info/rules"
+ name = "info/rules"
+
+ def get(self):
+ return self.render("main/info/rules.html")
diff --git a/static/resources.json b/static/resources.json
new file mode 100644
index 00000000..1e6bc503
--- /dev/null
+++ b/static/resources.json
@@ -0,0 +1,45 @@
+{
+ "Learning Resources": {
+ "description": "Tutorials and references for those that are just getting started with python",
+ "resources": {
+ "Automate the Boring Stuff with Python": {
+ "description": "One of the best books out there for Python beginners. You can buy a copy, but there's also a free online version.",
+ "url": "https://automatetheboringstuff.com/"
+ },
+ "Getting Started for Non-Programmers": {
+ "description": "The list of resources for non-programmers from Python's official beginners' guide",
+ "url": "https://wiki.python.org/moin/BeginnersGuide/NonProgrammers"
+ },
+ "Getting Started for Programmers": {
+ "description": "The list of resources for programmers from Python's official beginners' guide",
+ "url": "https://wiki.python.org/moin/BeginnersGuide/Programmers"
+ }
+ }
+ },
+ "Editors": {
+ "description": "Lightweight code editors supporting Python",
+ "resources": {
+ "Visual Studio Code (Free)": {
+ "description": "A fully-featured editor based on Electron, extendable with plugins.",
+ "url": "https://code.visualstudio.com/"
+ },
+ "Sublime Text (Paid, with shareware-style \"trial\")": {
+ "description": "A powerful Python-backed editor with great community support and a wealth of extensions.",
+ "url": "https://www.sublimetext.com/"
+ }
+ }
+ },
+ "IDEs": {
+ "description": "Fully-integrated development environments for serious Python work",
+ "resources": {
+ "PyCharm (Community and Professional editions available)": {
+ "description": "The very best Python IDE, with a wealth of advanced features and convenience functions.",
+ "url": "https://www.jetbrains.com/pycharm/"
+ },
+ "Spyder (Free)": {
+ "description": "The Scientific PYthon Development EnviRonment. Simpler and lighter than PyCharm, but still packs a punch.",
+ "url": "https://pythonhosted.org/spyder/"
+ }
+ }
+ }
+}
diff --git a/static/style.css b/static/style.css
index fbbec5c1..2b14c8ce 100644
--- a/static/style.css
+++ b/static/style.css
@@ -25,7 +25,7 @@
top: 45px !important;
}
-.uk-article-title a {
+.hover-title a {
visibility: hidden;
opacity: 0;
@@ -34,7 +34,7 @@
-webkit-transition: opacity 200ms ease-in-out;
}
-.uk-article-title:hover a {
+.hover-title:hover a {
visibility: visible;
opacity: 1;
@@ -54,4 +54,8 @@
.uk-section {
padding-top: 20px;
padding-bottom: 30px;
+}
+
+.uk-heading-divider .uk-article-meta {
+ margin-bottom: 0;
} \ No newline at end of file
diff --git a/templates/main/info/help.html b/templates/main/info/help.html
index d3084f8b..de041f66 100644
--- a/templates/main/info/help.html
+++ b/templates/main/info/help.html
@@ -4,7 +4,7 @@
<div class="uk-section">
<div class="uk-container uk-container-small">
<article class="uk-article">
- <h1 class="uk-article-title" id="top">
+ <h1 class="uk-article-title hover-title" id="top">
Getting Help
<a href="#top" class="uk-text-primary" title="Permanent link to this header">
@@ -26,7 +26,7 @@
behind that essay are in no way affiliated with us - please do not bother them with your Python
problems.
</p>
- <h2 class="uk-article-title" id="before">
+ <h2 class="uk-article-title hover-title" id="before">
Before You Ask
<a href="#before" class="uk-text-primary" title="Permanent link to this header">
@@ -110,7 +110,7 @@
whether someone else has asked your question recently, or just feel free to pick one of the help channels
and ask your question.
</p>
- <h2 class="uk-article-title" id="good-question">
+ <h2 class="uk-article-title hover-title" id="good-question">
A Good Question
<a href="#good-question" class="uk-text-primary" title="Permanent link to this header">
@@ -297,7 +297,7 @@
<div class="uk-section">
<div class="uk-container uk-container-small">
<article class="uk-article">
- <h2 class="uk-article-title" id="answers">
+ <h2 class="uk-article-title hover-title" id="answers">
Interpreting Answers
<a href="#answers" class="uk-text-primary" title="Permanent link to this header">
@@ -364,7 +364,7 @@
people applying actively them, visibly, in public.
</p>
- <h2 class="uk-article-title" id="what-not-to-ask">
+ <h2 class="uk-article-title hover-title" id="what-not-to-ask">
What Not To Ask
<a href="#what-not-to-ask" class="uk-text-primary" title="Permanent link to this header">
diff --git a/templates/main/info/resources.html b/templates/main/info/resources.html
new file mode 100644
index 00000000..576d68ec
--- /dev/null
+++ b/templates/main/info/resources.html
@@ -0,0 +1,56 @@
+{% extends "main/base.html" %}
+{% block title %}Resources{% endblock %}
+{% block content %}
+ <div class="uk-section">
+ <div class="uk-container uk-container-small">
+ <article class="uk-article">
+ <h1 class="uk-article-title hover-title" id="top">
+ Resources
+
+ <a href="#top" class="uk-text-primary" title="Permanent link to this header">
+ <i class="fas fa-paragraph" data-fa-transform="shrink-8"></i>
+ </a>
+ </h1>
+ <p class="uk-article-meta">
+ Learn you a Haskell for great- wait, wrong book
+ </p>
+ <p>
+ This page is intended to be a listing of useful resources for beginner and experienced Python
+ programmers alike. This page is generated from a JSON file
+ <a href="https://github.com/discord-python/site/blob/master/static/resources.json">on GitHub</a> -
+ if there's a great resource that you love and you don't see it on this page, feel free to submit a
+ pull request!
+ </p>
+
+ {% if categories is none %}
+ <div class="uk-alert-danger" uk-alert>
+ <p>
+ We were unable to load the <code>resources.json</code> file. If you see this, please
+ notify us!
+ </p>
+ </div>
+ {% else %}
+ {% for category_name, category_data in categories.items() %}
+ <h2 class="uk-heading-divider hover-title" id="{{ category_name.replace(" ", "-").lower() }}">
+ {{ category_name }}
+
+ <a href="#{{ category_name.replace(" ", "-").lower() }}" class="uk-text-primary" title="Permanent link to this header">
+ <i class="fas fa-paragraph" data-fa-transform="shrink-8"></i>
+ </a>
+ <br/>
+ <p class="uk-article-meta">
+ {{ category_data.description }}
+ </p>
+ </h2>
+ {% for item, data in category_data.resources.items() %}
+ <p>
+ <strong>{{ item }}</strong> &nbsp;<a href="{{ data.url }}"><i class="fas fa-link"></i></a><br />
+ <span class="uk-text-meta">{{ data.description }}</span>
+ </p>
+ {% endfor %}
+ {% endfor %}
+ {% endif %}
+ </article>
+ </div>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/templates/main/info/rules.html b/templates/main/info/rules.html
new file mode 100644
index 00000000..1853f090
--- /dev/null
+++ b/templates/main/info/rules.html
@@ -0,0 +1,116 @@
+{% extends "main/base.html" %}
+{% block title %}Rules{% endblock %}
+{% block content %}
+ <div class="uk-section">
+ <div class="uk-container uk-container-small">
+ <article class="uk-article">
+ <h1 class="uk-article-title hover-title" id="top">
+ Rules
+
+ <a href="#top" class="uk-text-primary" title="Permanent link to this header">
+ <i class="fas fa-paragraph" data-fa-transform="shrink-8"></i>
+ </a>
+ </h1>
+ <p class="uk-article-meta">
+ Keeping our noses clean since 2017
+ </p>
+ <p>
+ We have a small but strict set of rules on our server. Please read over them and take them on board -
+ if you don't understand anything or need some clarification, feel free to ask any staff member!
+ </p>
+ <ol>
+ <li>
+ Be polite, and do not spam
+ </li>
+ <li>
+ Follow the <a href="https://discordapp.com/guidelines">Discord community guidelines</a>
+ </li>
+ <li>
+ Be patient both with users asking questions, and the users answering them
+ </li>
+ <li>
+ Listen to and respect the staff members - we're here to help, but we're all human beings
+ </li>
+ <li>
+ All discussion should be kept within the relevant channels for the subject.
+ <ul>
+ <li>
+ General Python help and support requests go to one of the three help channels - pick
+ the one that is the quietest at the time.
+ </li>
+ <li>
+ The topical channels can be used for help and support requests, but general discussion
+ about the subjects covered by them should go there also.
+ </li>
+ <li>
+ If you're working with one of the bots, we ask you to specifically do that in
+ <code>#bot-commands</code>, to keep the other channels clear of bot output.
+ </li>
+ <li>
+ If you're working on a Python project or something directly related to our server, feel
+ free to post a link to it in <code>#show-your-projects</code>. We prefer links to source
+ code over websites, but we'll also accept screenshots and videos if you're not yet ready
+ to release the code.
+ <ul>
+ <li>
+ If you or someone else posts a project to <code>#show-your-projects</code>, you may
+ discuss it in <code>#show-your-projects-discussion</code>. <code>#show-your-projects</code>
+ is intended to be a listing channel, and any discussion there is removed regularly.
+ </li>
+ <li>
+ Please note, we <strong>do not</strong> allow postings for communities (such as
+ forums or other Discord servers) or commercial projects.
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ This is an English-speaking server. Please speak English to the best of your ability. Google
+ translate is fine if you're not sure.
+ </li>
+ <li>
+ Keep all discussions SFW - No <a href="https://www.wikiwand.com/en/Ecchi">ecchi</a>
+ or <a href="https://www.wikiwand.com/en/Not_safe_for_work">NSFW media</a>. If you wouldn't want
+ the entire world to know about your interest in it, it doesn't belong on this server.
+ </li>
+ <li>
+ We do not allow advertisements for communities or commercial projects - Contact us directly if
+ you want to discuss a partnership!
+ </li>
+ </ol>
+
+ <h1 class="uk-article-title hover-title" id="infractions">
+ Infractions
+
+ <a href="#infractions" class="uk-text-primary" title="Permanent link to this header">
+ <i class="fas fa-paragraph" data-fa-transform="shrink-8"></i>
+ </a>
+ </h1>
+ <p class="uk-article-meta">
+ Why you gotta be so rude?
+ </p>
+ <p>
+ We have a generally no-nonsense policy when it comes to our rules. If you notice someone breaking
+ them, feel free to mention or DM a staff member and we'll try to deal with it as soon as possible.
+ </p>
+ <p>
+ The possible actions we take based on infractions can include the following:
+ </p>
+ <ul>
+ <li>A public verbal/textual warning</li>
+ <li>A short temporary mute</li>
+ <li>A long temporary mute</li>
+ <li>A kick from the server</li>
+ <li>A temporary ban from the server</li>
+ <li>A permanent ban from the server</li>
+ </ul>
+ <p>
+ While we do discuss more serious matters internally before handing out a punishment, simpler
+ infractions are dealt with directly by individual staffers and the punishment they hand out is left
+ to their own decision-making.
+ </p>
+ </article>
+ </div>
+ </div>
+{% endblock %} \ No newline at end of file
diff --git a/templates/main/navigation.html b/templates/main/navigation.html
index 5b518822..3178895e 100644
--- a/templates/main/navigation.html
+++ b/templates/main/navigation.html
@@ -11,40 +11,54 @@
</a>
</div>
- <div class="uk-navbar-right uk-visible@m">
- <ul class="uk-navbar-nav">
+ <div class="uk-navbar-right">
+ <ul class="uk-navbar-nav uk-visible@m">
{% if current_page == "index" %}
<li class="uk-active"><a href="/"><i class="uk-icon fas fa-home"></i> &nbsp;Home</a></li>
{% else %}
<li><a href="/"><i class="uk-icon fas fa-home"></i> &nbsp;Home</a></li>
{% endif %}
<li><a href="/invite"><i class="uk-icon fab fa-discord"></i> &nbsp;Discord</a></li>
+ </ul>
+ <ul class="uk-navbar-nav">
<li>
<a><i class="uk-icon fas fa-chevron-down"></i></a>
<div class="uk-navbar-dropdown uk-background-secondary" uk-dropdown>
<ul class="uk-nav uk-navbar-dropdown-nav">
+ <li class="uk-nav-header uk-hidden@m">Navigation</li>
+ <li class="uk-nav-item uk-hidden@m"><a href="/"><i class="uk-icon fas fa-home"></i> &nbsp;Home</a></li>
+ <li class="uk-nav-item uk-hidden@m"><a href="/invite"><i class="uk-icon fab fa-discord"></i> &nbsp;Discord</a></li>
+ <li class="uk-nav-divider uk-hidden@m"></li>
+
+ {% if current_page.startswith("info") %}
+ <li class="uk-nav-header uk-active">Information</li>
+ {% else %}
+ <li class="uk-nav-header">Information</li>
+ {% endif %}
+
{% if current_page == "info/help" %}
<li class="uk-active"><a href="/info/help">Getting Help</a></li>
{% else %}
<li><a href="/info/help">Getting Help</a></li>
{% endif %}
+
+ {% if current_page == "info/rules" %}
+ <li class="uk-active"><a href="/info/rules">Server Rules</a></li>
+ {% else %}
+ <li><a href="/info/rules">Server Rules</a></li>
+ {% endif %}
+
+ {% if current_page == "info/resources" %}
+ <li class="uk-active"><a href="/info/resources">Resources</a></li>
+ {% else %}
+ <li><a href="/info/resources">Resources</a></li>
+ {% endif %}
+
<li class="uk-nav-divider"></li>
</ul>
</div>
</li>
</ul>
</div>
-
- <div class="uk-navbar-right uk-hidden@m">
- <button class="uk-button" style="font-size: 2em;"><i class="uk-icon fas fa-angle-down"></i></button>
- <div uk-dropdown>
- <ul class="uk-nav uk-dropdown-nav">
- <li class="uk-nav-item"><a href="/"><i class="uk-icon fas fa-home"></i> &nbsp;Home</a></li>
- <li class="uk-nav-item"><a href="/invite"><i class="uk-icon fab fa-discord"></i> &nbsp;Discord</a></li>
- <li class="uk-nav-item"><a href="/info/help"><i class="uk-icon fas fa-question"></i> &nbsp;Getting Help</a></li>
- </ul>
- </div>
- </div>
-
</nav>
</div>