From 592b8ec1f0b504b60965939045431d7989869073 Mon Sep 17 00:00:00 2001
From: Gareth Coles
Date: Wed, 11 Apr 2018 20:39:48 +0100
Subject: Update resources page with new icons and formatting.
NOTE: This does change the JSON!
---
pysite/views/main/info/resources.py | 39 ++++++++++
static/images/payment_icons/green.svg | 1 +
static/images/payment_icons/red.svg | 1 +
static/images/payment_icons/yellow.svg | 1 +
static/resources.json | 133 ++++++++++++++++++++++++++++-----
templates/main/info/resources.html | 48 ++++++------
6 files changed, 179 insertions(+), 44 deletions(-)
create mode 100644 static/images/payment_icons/green.svg
create mode 100644 static/images/payment_icons/red.svg
create mode 100644 static/images/payment_icons/yellow.svg
diff --git a/pysite/views/main/info/resources.py b/pysite/views/main/info/resources.py
index ceb88b65..2642e1ec 100644
--- a/pysite/views/main/info/resources.py
+++ b/pysite/views/main/info/resources.py
@@ -4,9 +4,48 @@ from logging import getLogger
from pysite.base_route import RouteView
+ICON_STYLES = {
+ "branding": "fab",
+ "regular": "far",
+ "solid": "fas",
+ "light": "fal"
+}
+
+logger = getLogger("Resources")
+
try:
with open("static/resources.json") as fh:
categories = json.load(fh)
+
+ for category, items in categories.items():
+ to_remove = []
+
+ for name, resource in items["resources"].items():
+ for url_obj in resource["urls"]:
+ icon = url_obj["icon"].lower()
+
+ if "/" not in icon:
+ to_remove.append(name)
+ logger.error(
+ f"Resource {name} in category {category} has an invalid icon. Icons should be of the"
+ f"form `style/name`."
+ )
+ continue
+
+ style, icon_name = icon.split("/")
+
+ if style not in ICON_STYLES:
+ to_remove.append(name)
+ logger.error(
+ f"Resource {name} in category {category} has an invalid icon style. Icon style must "
+ f"be one of {', '.join(ICON_STYLES.keys())}."
+ )
+ continue
+
+ url_obj["classes"] = f"{ICON_STYLES[style]} fa-{icon_name}"
+
+ for name in to_remove:
+ del items["resources"][name]
except Exception:
getLogger("Resources").exception("Failed to load resources.json")
categories = None
diff --git a/static/images/payment_icons/green.svg b/static/images/payment_icons/green.svg
new file mode 100644
index 00000000..317ec1bf
--- /dev/null
+++ b/static/images/payment_icons/green.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/images/payment_icons/red.svg b/static/images/payment_icons/red.svg
new file mode 100644
index 00000000..854334d4
--- /dev/null
+++ b/static/images/payment_icons/red.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/images/payment_icons/yellow.svg b/static/images/payment_icons/yellow.svg
new file mode 100644
index 00000000..76a0bf4d
--- /dev/null
+++ b/static/images/payment_icons/yellow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/resources.json b/static/resources.json
index 87b4dd4f..210021d1 100644
--- a/static/resources.json
+++ b/static/resources.json
@@ -4,49 +4,106 @@
"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/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://automatetheboringstuff.com/",
+ "icon": "regular/link"
+ }, {
+ "title": "Amazon",
+ "url": "http://www.amazon.com/gp/product/1593275994/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1593275994&linkCode=as2&tag=playwithpyth-20&linkId=HDM7V3T6RHC5VVN4",
+ "icon": "branding/amazon"
+ }
+ ],
"payment": "optional",
"payment_description": "A free version is available online, with the option to buy a physical copy"
},
"Code Combat": {
"description": "Learn Python while gaming - an open-source project with thousands of contributors, which teaches you Python through a deep, top-down RPG.",
- "url": "https://codecombat.com/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://codecombat.com/",
+ "icon": "regular/link"
+ },
+ {
+ "title": "GitHub",
+ "url": "https://github.com/codecombat/codecombat",
+ "icon": "branding/github"
+ }
+ ],
"payment": "optional",
"payment_description": "A wealth of free content is available, but you can also pay for more"
},
"Get Started with Flask Web Development": {
"description": "A fully featured mega-tutorial for learning how to create web applications with the Flask framework.",
- "url": "https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
},
"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",
+ "urls": [
+ {
+ "title": "Python Wiki",
+ "url": "https://wiki.python.org/moin/BeginnersGuide/NonProgrammers",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
},
"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",
+ "urls": [
+ {
+ "title": "Python Wiki",
+ "url": "https://wiki.python.org/moin/BeginnersGuide/Programmers",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
},
"A Simple Guide to Git": {
"description": "A simple, no-nonsense guide to the basics of using Git.",
- "url": "http://rogerdudler.github.io/git-guide/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "http://rogerdudler.github.io/git-guide/",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
},
"Python Cheat Sheet": {
- "description": "A Python 3 cheat sheet with useful information and tips, as well as common pitfalls for beginners.",
- "url": "https://perso.limsi.fr/pointal/_media/python:cours:mementopython3-english.pdf",
+ "description": "A Python 3 cheat sheet with useful information and tips, as well as common pitfalls for beginners. This is a PDF.",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://perso.limsi.fr/pointal/_media/python:cours:mementopython3-english.pdf",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
},
"Python Tutorials by Corey Schafer on YouTube": {
"description": "An in-depth look at the Python programming language, from one of YouTube's most popular Python tutors.",
- "url": "https://www.youtube.com/playlist?list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU",
+ "urls": [
+ {
+ "title": "YouTube",
+ "url": "https://www.youtube.com/playlist?list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU",
+ "icon": "branding/youtube"
+ }
+ ],
"payment": "free",
"payment_description": null
}
@@ -55,21 +112,44 @@
"Editors": {
"description": "Lightweight code editors supporting Python",
"resources": {
- "Atom (Free)": {
+ "Atom": {
"description": "A free Electron-based editor, a \"hackable text editor for the 21st century\", maintained by the GitHub team.",
- "url": "https://atom.io/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://atom.io/",
+ "icon": "regular/link"
+ },
+ {
+ "title": "GitHub",
+ "url": "https://github.com/atom/atom",
+ "icon": "branding/github"
+ }
+ ],
"payment": "free",
"payment_description": null
},
- "Sublime Text (Paid, with shareware-style \"trial\")": {
+ "Sublime Text": {
"description": "A powerful Python-backed editor with great community support and a wealth of extensions.",
- "url": "https://www.sublimetext.com/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://www.sublimetext.com/",
+ "icon": "regular/link"
+ }
+ ],
"payment": "optional",
"payment_description": "Nagware; will ask you to buy the full version after every X saves"
},
- "Visual Studio Code (Free)": {
+ "Visual Studio Code": {
"description": "A fully-featured editor based on Electron, extendable with plugins.",
- "url": "https://code.visualstudio.com/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://code.visualstudio.com/",
+ "icon": "regular/link"
+ }
+ ],
"payment": "free",
"payment_description": null
}
@@ -80,13 +160,30 @@
"resources": {
"PyCharm": {
"description": "The very best Python IDE, with a wealth of advanced features and convenience functions.",
- "url": "https://www.jetbrains.com/pycharm/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://www.jetbrains.com/pycharm/",
+ "icon": "regular/link"
+ }
+ ],
"payment": "optional",
"payment_description": "There's a free Community Edition and a paid-for Professional Edition with more features available"
},
- "Spyder (Free)": {
+ "Spyder": {
"description": "The Scientific PYthon Development EnviRonment. Simpler and lighter than PyCharm, but still packs a punch.",
- "url": "https://pythonhosted.org/spyder/",
+ "urls": [
+ {
+ "title": "Website",
+ "url": "https://pythonhosted.org/spyder/",
+ "icon": "regular/link"
+ },
+ {
+ "title": "GitHub",
+ "url": "https://github.com/spyder-ide/spyder",
+ "icon": "branding/github"
+ }
+ ],
"payment": "free",
"payment_description": null
}
diff --git a/templates/main/info/resources.html b/templates/main/info/resources.html
index 7bf5827d..c947d4ed 100644
--- a/templates/main/info/resources.html
+++ b/templates/main/info/resources.html
@@ -29,20 +29,11 @@
mobile).
-
-
-
-
+
Free
-
-
-
-
+
Payment Optional
-
-
-
-
+
Paid
@@ -68,26 +59,31 @@
{% for item, data in category_data.resources.items() %}
- {% if data["payment_description"] %}
-
+ {% if data["payment"] == "optional" %}
+ {% set file_path = static_file("images/payment_icons/yellow.svg") %}
+ {% elif data["payment"] == "paid" %}
+ {% set file_path = static_file("images/payment_icons/red.svg") %}
{% else %}
-
+ {% set file_path = static_file("images/payment_icons/green.svg") %}
{% endif %}
- {% if data["payment"] == "optional" %}
-
-
- {% elif data["payment"] == "paid" %}
-
-
+ {% if data["payment_description"] %}
+
{% else %}
-
-
+
{% endif %}
-
- {{ item }}
+
-
+
{{ data.description }}
{% endfor %}
--
cgit v1.2.3