Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 131 additions & 93 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pydis_site/apps/api/models/bot/metricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
]


class NotFound(Exception):
class NotFound(Exception): # noqa: N818
"""Raised when an entity cannot be found."""

pass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
description: This tutorial, written by Python Discord staff member vcokltfre,
will walk you through all the aspects of creating your own Discord bot,
starting from from creating the bot user itself.
name: vcokltfre's Discord Bot Tutorial
title_url: https://vcokltfre.dev/
tags:
topics:
- discord bots
payment_tiers:
- free
complexity:
- intermediate
type:
- tutorial
38 changes: 38 additions & 0 deletions pydis_site/apps/resources/templatetags/get_category_icon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django import template

register = template.Library()


@register.filter
def get_category_icon(name: str) -> str:
"""Get icon of a specific resource category."""
icons = {
"Algorithms And Data Structures": "fa-cogs",
"Data Science": "fa-flask",
"Databases": "fa-server",
"Game Development": "fa-joystick",
"General": "fa-book",
"Microcontrollers": "fa-microchip",
"Other": "fa-question-circle",
"Software Design": "fa-paint-brush",
"Testing": "fa-vial",
"Tooling": "fa-toolbox",
"User Interface": "fa-desktop",
"Web Development": "fa-wifi",
"Discord Bots": "fa-robot",
"Book": "fa-book",
"Community": "fa-users",
"Course": "fa-chalkboard-teacher",
"Interactive": "fa-mouse-pointer",
"Podcast": "fa-microphone-alt",
"Tool": "fa-tools",
"Tutorial": "fa-clipboard-list",
"Video": "fa-video",
"Free": "fa-first-aid",
"Paid": "fa-sack",
"Subscription": "fa-credit-card",
"Beginner": "fa-play-circle",
"Intermediate": "fa-align-center"
}
icon_name = icons[name]
Comment on lines +9 to +37
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dictionary should be a global so that it's not being re-created each time. Try naming it _ICONS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure Python handles this and uses LOAD CONST, that said using an all-caps variable at the top of the file is cleaner.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I wish we had function composition so that this function could just be get_category_icon = register.filter @ 'fa {icon_name}'.format @ icons.get, but no 😞

return f'fa {icon_name}'
2 changes: 1 addition & 1 deletion pydis_site/apps/resources/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def _transform_name(resource_name: str) -> str:

RESOURCE_TABLE = {category: defaultdict(set) for category in (
"topics",
"payment_tiers",
"payment_tiers",
"complexity",
"type"
)}
Expand Down
5 changes: 4 additions & 1 deletion pydis_site/apps/resources/views/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ def resource_view(request: HttpRequest) -> HttpResponse:
)
}

topics = sorted(RESOURCE_META_TAGS.get("topics"))

return render(
request,
template_name="resources/resources.html",
context={
"checkboxOptions": checkbox_options,
"topics": sorted(RESOURCE_META_TAGS.get("topics")),
"topics_1": topics[:len(topics) // 2],
"topics_2": topics[len(topics) // 2:],
Comment on lines +33 to +34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to double check that this doesn't affect the back end logic in any way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't

"tag_types": sorted(RESOURCE_META_TAGS.get("type")),
"payment_tiers": sorted(RESOURCE_META_TAGS.get("payment_tiers")),
"complexities": sorted(RESOURCE_META_TAGS.get("complexity")),
Expand Down
1 change: 0 additions & 1 deletion pydis_site/static/css/resources/resources_list.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,3 @@ i.has-icon-padding {
#tab-content p.is-active {
display: block;
}

33 changes: 25 additions & 8 deletions pydis_site/templates/resources/resource_box.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% load as_icon %}
{% load get_category_icon %}

<div class="box" style="max-width: 800px;">
{% if 'title_url' in resource %}
Expand All @@ -11,12 +12,28 @@

<p class="is-italic">{{ resource.description|safe }}</p>

{# Icons #}
{% for icon in resource.urls %}
<span class="icon is-size-4 is-medium" style="margin: 5px;">
<a href="{{ icon.url }}">
<i class="{{ icon.icon|as_icon }} is-size-3 resource-icon is-{{ icon.color }}"></i>
</a>
</span>
{% endfor %}
<div class="is-flex is-align-items-center">
{# Icons #}
{% for icon in resource.urls %}
<span class="icon is-size-4 is-medium" style="margin: 5px;">
<a href="{{ icon.url }}">
<i class="{{ icon.icon|as_icon }} is-size-3 resource-icon is-{{ icon.color }}"></i>
</a>
</span>
{% endfor %}
<div class="is-flex ml-auto is-flex-wrap-wrap is-justify-content-end">
{% for tag in resource.tags.topics %}
<span class="tag is-primary is-light ml-2 mt-2"><i class="{{ tag|title|get_category_icon }} mr-1"></i>{{ tag|title }}</span>
{% endfor %}
{% for tag in resource.tags.type %}
<span class="tag has-background-success-light has-text-success-dark ml-2 mt-2"><i class="{{ tag|title|get_category_icon }} mr-1"></i>{{ tag|title }}</span>
{% endfor %}
{% for tag in resource.tags.payment_tiers %}
<span class="tag has-background-danger-light has-text-danger-dark ml-2 mt-2"><i class="{{ tag|title|get_category_icon }} mr-1"></i>{{ tag|title }}</span>
{% endfor %}
{% for tag in resource.tags.complexity %}
<span class="tag has-background-info-light has-text-info-dark ml-2 mt-2"><i class="{{ tag|title|get_category_icon }} mr-1"></i>{{ tag|title }}</span>
{% endfor %}
</div>
</div>
</div>
144 changes: 90 additions & 54 deletions pydis_site/templates/resources/resources.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,89 +9,114 @@
{% endblock %}

{% block content %}
{% include "base/navbar.html" %}

<section class="section">
<div class="container">
<div class="content">
<h1 class="resource-title has-text-centered">Resources</h1>
<hr/>
</div>
<div class="panel is-hidden-mobile">
<p class="panel-heading has-text-centered">Search Options</p>

<div class="field">
<div class="columns">
<div class="column pl-6">
<div class="title is-5 pt-2 has-text-centered">Topic</div>

{% for topic in topics %}
<div class="field">
<label class="checkbox">
<input name="topicOption" type="checkbox" value="{{ topic }}">
<span class="has-text-grey is-size-6">{{ topic }}</span>
</label>
{% include "base/navbar.html" %}

<section class="section">
<div class="container">
<div class="content">
<h1 class="resource-title has-text-centered">Resources</h1>
<hr/>
</div>
<div class="panel is-hidden-mobile">
<p class="panel-heading has-text-centered">Search Options</p>

<div class="field">
<div class="columns">
<div class="column pl-6 is-two-fifths is-flex is-flex-direction-column">
<div class="title is-5 pt-2 has-text-centered">Topic</div>
<div class="columns">
<div class="column">
{% for topic in topics_1 %}
<div class="field">
<label class="checkbox">
<input class="topic" name="topicOption" type="checkbox" value="{{ topic }}"{% if topic == 'General' %} checked{% endif %}>
<span class="has-text-grey is-size-6">{{ topic }}</span>
</label>
</div>
{% endfor %}
</div>
<div class="column">
{% for topic in topics_2 %}
<div class="field">
<label class="checkbox">
<input class="topic" name="topicOption" type="checkbox" value="{{ topic }}"{% if topic == 'General' %} checked{% endif %}>
<span class="has-text-grey is-size-6">{{ topic }}</span>
</label>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
<span class="control ml-2 is-flex is-align-items-end is-justify-content-center mt-auto">
<button onclick="selectAllQueryParams('topic')" class="button is-success is-small">Select All</button>
</span>
</div>

<div class="column pl-6">
<div class="column is-flex is-flex-direction-column pl-6">
<div class="title is-5 pt-2 has-text-centered">Type</div>

{% for tag_type in tag_types %}
<div class="field">
<label class="checkbox ml-0">
<input name="typeOption" type="checkbox" value="{{ tag_type }}">
<span class="has-text-grey is-size-6">{{ tag_type }}</span>
</label>
<label class="checkbox ml-0">
<input class="type" name="typeOption" type="checkbox" value="{{ tag_type }}"{% if tag_type == 'Tutorial' %} checked{% endif %}>
<span class="has-text-grey is-size-6">{{ tag_type }}</span>
</label>
</div>
{% endfor %}
{% endfor %}
<span class="control ml-2 is-flex is-align-items-end is-justify-content-center mt-auto">
<button onclick="selectAllQueryParams('type')" class="button is-success is-small">Select All</button>
</span>
</div>

<div class="column pl-6">
<div class="column is-flex is-flex-direction-column pl-6">
<div class="title is-5 pt-2 has-text-centered">Payment</div>

{% for payment_tier in payment_tiers %}
<div class="field">
<label class="checkbox ml-0">
<input name="paymentOption" type="checkbox" value="{{ payment_tier }}">
<span class="has-text-grey is-size-6">{{ payment_tier }}</span>
</label>
<label class="checkbox ml-0">
<input class="payment" name="paymentOption" type="checkbox" value="{{ payment_tier }}"{% if payment_tier == 'Free' %} checked{% endif %}>
<span class="has-text-grey is-size-6">{{ payment_tier }}</span>
</label>
</div>
{% endfor %}
{% endfor %}
<span class="control ml-2 is-flex is-align-items-end is-justify-content-center mt-auto">
<button onclick="selectAllQueryParams('payment')" class="button is-success is-small">Select All</button>
</span>
</div>

<div class="column pl-6">
<div class="column is-flex is-flex-direction-column px-6">
<div class="title is-5 pt-2 has-text-centered">Level</div>

{% for complexity in complexities %}
<div class="field">
<label class="checkbox ml-0">
<input name="complexityOption" type="checkbox" value="{{ complexity }}">
<span class="has-text-grey is-size-6">{{ complexity }}</span>
<label class="checkbox ml-0">
<input class="complexity" name="complexityOption" type="checkbox" value="{{ complexity }}"{% if complexity == 'Beginner' %} checked{% endif %}>
<span class="has-text-grey is-size-6">{{ complexity }}</span>
</label>
</div>
{% endfor %}
{% endfor %}
<span class="control ml-2 is-flex is-align-items-end is-justify-content-center mt-auto">
<button onclick="selectAllQueryParams('complexity')" class="button is-success is-small">Select All</button>
</span>
</div>
</div>
</div>

<div class="ml-3 pb-3">
<span class="control">
<button onclick="buildQueryParams()" class="button is-link is-small">Search</button>
</span>
<div class="is-flex is-justify-content-center pb-3">
<span class="control mr-2">
<button onclick="buildQueryParams()" class="button is-link is-small">Search</button>
</span>

<span class="is-one-fifth control">
<button onclick="clearQueryParams()" class="button is-danger is-small">Clear Search</button>
</span>
</div>
</div>
</div>
</section>
<span class="is-one-fifth control is-flex is-align-items-end is-justify-content-end mt-auto">
<button onclick="clearQueryParams()" class="button is-danger is-small">Clear Search</button>
</span>
</div>
</div>
</div>
</section>

{% if resources|length > 0 %}
<section class="section">
<div class="container">
<div class="content">
<div class="content is-flex is-justify-content-center">
<div>
{% for resource in resources %}
{% include "resources/resource_box.html" %}
Expand Down Expand Up @@ -160,5 +185,16 @@ <h2 class="title is-3 has-text-centered pt-0 pb-6 ">No resources matching search
});
});
}

function selectAllQueryParams(column){
checkboxOptions.forEach((option) => {
document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => {
if (checkbox.className == column) {
checkbox.checked = true;
}
});
});
}

</script>
{% endblock %}
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ django-environ = "~=0.4.5"
django-filter = "~=2.1.0"
django-hosts = "~=4.0"
djangorestframework = "~=3.11.0"
psycopg2-binary = "~=2.8"
django-simple-bulma = "~=2.1"
psycopg2-binary = "~=2.8.0"
django-simple-bulma = "~=2.4"
whitenoise = "~=5.0"
requests = "~=2.21"
pyyaml = "~=5.1"
Expand Down