Apparently some updates I forgot to add again...
- Author
- Maarten Vangeneugden
- Date
- May 22, 2021, 3:02 p.m.
- Hash
- 3f7d9a15e2d80185aa13db6054c21d386b134fc3
- Parent
- 078683599bfc42112adada4f22ba6dd1b9df0a5d
- Modified files
- forms.py
- templates/about/main_content.djhtml
- views.py
forms.py ¶
1 addition and 0 deletions.
templates/about/main_content.djhtml ¶
5 additions and 5 deletions.
View changes Hide changes
1 |
1 |
{% load static %} |
2 |
2 |
<section class="emphasis"> |
3 |
3 |
<h1>{% trans "Welcome!" %}</h1> |
4 |
4 |
<p> |
5 |
5 |
{% blocktrans %}Hello there! I'm Maarten, a happy |
6 |
6 |
student from Belgium, and this is my amazing personal website. |
7 |
7 |
I like a lot of things, and I share some of those in here. Take |
8 |
8 |
a look around, read a bit, talk with me, and most importantly, |
9 |
9 |
enjoy your stay!{% endblocktrans %} |
10 |
10 |
</p> |
11 |
11 |
</section> |
12 |
12 |
<div class="cards"> |
13 |
13 |
{# Blog card #} |
14 |
14 |
<div id="blog" class="card"> |
15 |
15 |
<img src="/media/main/blog.jpg" /> |
16 |
16 |
<h3>{% trans "Blog" %}</h3> |
17 |
17 |
<p> |
18 |
18 |
{% blocktrans %}My personal scribblepad, written from scratch, |
19 |
19 |
on which I ramble about everything I like. Highly recommended |
20 |
20 |
while eating breakfast.{% endblocktrans %} |
21 |
21 |
</p> |
22 |
22 |
<a class="btn text" href="{% url 'blog-index' %}">{% trans "Visit blog" %}</a> |
23 |
23 |
</div> |
24 |
24 |
|
25 |
25 |
{# Gitar card #} |
26 |
26 |
<div id="gitar" class="card" style="flex-grow: 2"> |
27 |
27 |
<!-- HAHAHAA I CAN'T DESIGN LOGOS --> |
28 |
28 |
<img src="/media/main/gitar.png" /> |
29 |
29 |
<h3>Gitar</h3> |
30 |
30 |
<p> |
31 |
31 |
{% blocktrans %}I actually don't use GitHub to host my code, |
32 |
32 |
contrary to a lot of other coders. Instead, I've been trying to |
33 |
33 |
create something that's just fit to my taste. I host a couple of |
34 |
34 |
archive repositories there, as well as dotfiles, and that jazz. It's |
35 |
35 |
a continuing work, so don't flip your desk if the layout is upside |
36 |
36 |
down tomorrow =3{% endblocktrans %} |
37 |
37 |
</p> |
38 |
38 |
<a class="btn text" href="{% url 'gitar-index' %}"> |
39 |
39 |
{% trans "Check code" %}</a> |
40 |
40 |
</div> |
41 |
41 |
|
42 |
42 |
{# About myself card #} |
43 |
43 |
<div id="about" class="card"> |
44 |
44 |
<img src="/media/about/images/parallax.png" /> |
45 |
45 |
<!-- I still don't have a good picture or still life about |
46 |
46 |
myself, so yes, I'm copying my parallax for a while. Sorry! --> |
47 |
47 |
<h3>{% trans "About me" %}</h3> |
48 |
48 |
<p> |
49 |
49 |
{% blocktrans %}Well, if you wish to know more of me, I have a page |
50 |
50 |
where I describe myself in a couple more sentences. You know, |
51 |
51 |
because I can =) |
52 |
52 |
{% endblocktrans %} |
53 |
53 |
</p> |
54 |
54 |
<a class="btn text" href="{% url "main-myself" %}">{% trans "Read on" %}</a> |
55 |
55 |
</div> |
56 |
56 |
|
57 |
57 |
{# Publications card #} |
58 |
58 |
<div id="eldonoj" class="card"> |
59 |
59 |
<!--<img src="/media/about/images/publications.png" />--> |
60 |
60 |
<h3>{% translate "Publications" %}</h3> |
61 |
61 |
<p> |
62 |
62 |
{% blocktranslate %}Throughout my academic career, I've written a lot, |
63 |
63 |
sometimes together with other people. To avoid that these papers get |
64 |
64 |
lost to the passing of time, I've decided to publish them on my website, should somebody |
65 |
65 |
want to read them.{% endblocktranslate %} |
66 |
66 |
</p> |
67 |
67 |
<a class="btn text" href="{% url "publications-index" %}">{% translate "Consult publications" %}</a> |
68 |
68 |
</div> |
69 |
69 |
|
70 |
70 |
{# Projects card #} |
71 |
71 |
<div id="project" class="card"> |
72 |
72 |
<h3>{% trans "Other projects" %}</h3> |
73 |
73 |
<p> |
74 |
74 |
{% blocktrans %}Projects come and go, and with my website I can |
75 |
75 |
present them to you. This cards takes you to the |
76 |
76 |
archive of past projects. |
77 |
77 |
{% endblocktrans %} |
78 |
78 |
</p> |
79 |
79 |
<a class="btn text disabled" href="{% url "main-project-archive" %}"> |
80 |
80 |
{% trans "View projects" %}</a> |
81 |
81 |
</div> |
82 |
82 |
|
83 |
83 |
{# Activism card #} |
84 |
84 |
<div id="aktivismo" class="card"> |
85 |
85 |
<h3>{% trans "Activism" %}</h3> |
86 |
86 |
<p> |
87 |
87 |
{% blocktrans %}Trying to make this place better takes some time. So |
88 |
88 |
I made a page in the hopes that it can engage you to partake in that |
89 |
89 |
process. Because it's never too late to begin. |
90 |
90 |
{% endblocktrans %} |
91 |
91 |
</p> |
92 |
92 |
<a class="btn text" href="{% url "activism" %}"> |
93 |
93 |
{% trans "List talking points" %}</a> |
94 |
94 |
</div> |
95 |
95 |
|
96 |
96 |
</div> |
97 |
97 |
{% if contact_response %} |
98 |
98 |
<div class="snackbar"> |
99 |
99 |
{{ contact_response }} |
100 |
100 |
</div> |
101 |
101 |
{% endif %} |
102 |
102 |
<!--<section> |
103 |
103 |
<h2>{% translate "Friends of me" %}</h2> |
104 |
104 |
<!-- TODO: Een inleidende tekst bedenken hiervoor --> |
105 |
- | </section>--> |
+ |
105 |
</section>--> |
106 |
106 |
<section> |
107 |
107 |
<h2>{% translate "Contact me" %}</h2> |
108 |
108 |
<p>{% blocktranslate %}If you wish to contact me, use this convenient form, |
109 |
109 |
the most direct link to yours truly. Leave me a thank you note, tell me |
110 |
110 |
something important, or correct a typo I made, it's all good, I love to |
111 |
111 |
hear from you! |
112 |
112 |
If necessary, put some contact info of yourself in your message so I can get |
113 |
- | back to you. Do <em>not</em> put a hyperlink in your message. Adding a |
+ |
113 |
back to you. Do <em>not</em> put a hyperlink in your message. Adding a |
114 |
114 |
hyperlink will put automatically ban your computer from my website |
115 |
115 |
and probably make it explode, so don't do that.{% endblocktranslate %}</p> |
116 |
- | <form action="" method="post"> |
+ |
116 |
<form action="" method="post"> |
117 |
117 |
{% csrf_token %} |
118 |
118 |
<input type="text" name="name" mozactionhint="send" enterkeyhint="send" maxlength="64" placeholder="{% translate "Your name" %}" required> |
119 |
119 |
<br> |
120 |
120 |
<textarea maxlength="2000" spellcheck="true" name="message" required></textarea> |
121 |
121 |
<br> |
122 |
122 |
<p>{% blocktranslate %}Bot check: Correctly enter the name of any Belgian province in |
123 |
- | one of the three Belgian languages:{% endblocktranslate %}</p> |
124 |
- | <input type="text" name="provincio" mozactionhint="send" enterkeyhint="send" maxlength="64" placeholder="{% translate "Province" %}" required> |
+ |
123 |
one of the three Belgian languages (just check Wikipedia!):{% endblocktranslate %}</p> |
+ |
124 |
<input type="text" name="provincio" mozactionhint="send" enterkeyhint="send" maxlength="64" placeholder="{% translate "Province" %}" required> |
125 |
125 |
<input type="submit" value="✉️ {% translate "Send" %}"> |
126 |
126 |
</form> |
127 |
127 |
</section> |
128 |
128 |
views.py ¶
7 additions and 3 deletions.
View changes Hide changes
1 |
1 |
import requests # For direct communication with me |
2 |
2 |
from datetime import date |
3 |
3 |
from django.utils import timezone |
4 |
4 |
from django.shortcuts import get_object_or_404, render # This allows to render the template with the view here. It's pretty cool and important. |
5 |
5 |
from django.http import HttpResponseRedirect, HttpResponse # Why? |
6 |
6 |
from django.urls import reverse # Why? |
7 |
7 |
from django.utils.translation import ugettext as _ |
8 |
- | from .models import * |
+ |
8 |
from .models import * |
9 |
9 |
from .forms import MessageForm |
10 |
10 |
from ipware import get_client_ip |
11 |
11 |
|
12 |
12 |
|
13 |
13 |
def get_age(): |
14 |
14 |
"""Returns my current age.""" |
15 |
15 |
today = date.today() |
16 |
16 |
birthday = date(1996, 8, 28) |
17 |
17 |
age = today - birthday |
18 |
18 |
years = str(int(age.days / 365)) |
19 |
19 |
return years |
20 |
20 |
|
21 |
21 |
def footer_description(): |
22 |
22 |
return _("Main pages of Maarten's website, a %(years)s year old Belgian programmer. Also an undergraduate student of Informatics @ UHasselt, and graduate student of Engineering Informatics at Ghent University.") % {'years': get_age()} |
23 |
23 |
|
24 |
24 |
def footer_links(): |
25 |
25 |
footer_links = [ |
26 |
26 |
[_("Contact me"), "mailto:maarten.vangeneugden@student.uhasselt.be"], |
27 |
27 |
[_("Hasselt University"), "https://www.uhasselt.be"], |
28 |
28 |
[_("Ghent University"), "https://www.ugent.be"], |
29 |
29 |
] |
30 |
30 |
return footer_links |
31 |
31 |
|
32 |
32 |
# TODO: Move this stuff to the template module. This is basically a description |
33 |
33 |
# of HOW to display data, but the view module is only responsible for WHAT data |
34 |
34 |
# to display. |
35 |
35 |
def standard_context(): |
36 |
36 |
context = { |
37 |
37 |
'navbar_backArrow': True, |
38 |
38 |
'footer_title': _("Home page"), |
39 |
39 |
'footer_description': footer_description(), |
40 |
40 |
'footer_links': footer_links(), |
41 |
41 |
'stylesheet_name': "home", |
42 |
42 |
} |
43 |
43 |
return context |
44 |
44 |
|
45 |
45 |
def get_current_status(dt = None): |
46 |
46 |
"""Returns a string specifying my current state (and sometimes location). |
47 |
47 |
|
48 |
48 |
This function is actually based on my weekly schedule. I'd normally hook it |
49 |
49 |
up to my iCal files, but that doesn't include things like sleeping. Not to |
50 |
50 |
mention my university has a hard time following standards like "Put the |
51 |
51 |
location in the location field, not in the title of the appointment". I |
52 |
52 |
figured a simple function would do the job just as well. |
53 |
53 |
|
54 |
54 |
Keyword arguments: |
55 |
55 |
dt -- The datetime object of the day to check (defaults to current local time) |
56 |
56 |
""" |
57 |
57 |
|
58 |
58 |
MONDAY = 0 |
59 |
59 |
TUESDAY = 1 |
60 |
60 |
WEDNESDAY = 2 |
61 |
61 |
THURSDAY = 3 |
62 |
62 |
FRIDAY = 4 |
63 |
63 |
SATURDAY = 5 |
64 |
64 |
SUNDAY = 6 |
65 |
65 |
|
66 |
66 |
if dt is None: |
67 |
67 |
timezone.activate("Europe/Brussels") |
68 |
68 |
dt = timezone.localtime(timezone.now()) |
69 |
69 |
|
70 |
70 |
day = dt.weekday() |
71 |
71 |
hour = dt.time().hour |
72 |
72 |
minute = dt.time().minute |
73 |
73 |
|
74 |
74 |
""" Note on usage of the range() function: |
75 |
75 |
range(x, y) returns a list, beginning from x, but excluding y. So if a |
76 |
76 |
course runs from 13:00 to 15:00, then y should still be 15. Why? Because |
77 |
77 |
that makes it so that 14:59 is included, but 15:00 is not. if y would be 16, |
78 |
78 |
then 15:30 would also be included. |
79 |
79 |
""" |
80 |
80 |
|
81 |
81 |
# If nothing's returned by now, return a general response |
82 |
82 |
return _("Probably chilling a bit. Feel free to talk! ❤") |
83 |
83 |
|
84 |
84 |
def send_message(name, ip, message): |
85 |
85 |
""" Sends a message to me if the visitor submits one on my website. """ |
86 |
86 |
# First task: Retrieve the token, which mustn't be in the tracker: |
87 |
87 |
with open("token.txt", 'r') as f: |
88 |
88 |
url = f.readline() |
89 |
89 |
url += name + " (" +str(ip)+ ") stuurt:\n" + message |
90 |
90 |
|
91 |
91 |
response = requests.get(url) |
92 |
92 |
return response.status_code == 200 |
93 |
93 |
|
94 |
94 |
def contains_hyperlink(string): |
95 |
95 |
return ("https://" in string.lower() or "http://" in string.lower()) |
96 |
96 |
|
97 |
97 |
|
98 |
98 |
def add_to_bots(request): |
99 |
99 |
client_ip, is_routable = get_client_ip(request) |
100 |
100 |
if client_ip is not None: |
101 |
101 |
with open('blog/bot-ip-addresses.txt', 'a') as f: |
102 |
102 |
print("deny " + str(client_ip) + "; # Abused contact form.", file=f) |
103 |
103 |
|
104 |
104 |
|
105 |
105 |
# Views: |
106 |
106 |
|
107 |
107 |
def index(request): |
108 |
- | context = standard_context() |
+ |
108 |
from django.utils.translation import gettext as _ |
+ |
109 |
context = standard_context() |
109 |
110 |
# First, handle possible contact |
110 |
111 |
if request.method == "POST": # Message received |
111 |
112 |
form = MessageForm(request.POST) |
112 |
113 |
if form.is_valid(): |
113 |
114 |
clean_message = form.cleaned_data |
114 |
115 |
# Bot test: |
115 |
116 |
if clean_message["provincio"].lower() not in [ |
116 |
117 |
"limburg", "limbourg", |
117 |
118 |
"antwerpen", "anvers", "antorf", "antorff", |
118 |
119 |
"vlaams-brabant", "brabant flamand", "flämisch-brabant", |
119 |
120 |
"oost-vlaanderen", "flandre-orientale", "ostflandern", |
120 |
121 |
"west-vlaanderen", "flandre-occidentale", "westflandern", |
121 |
122 |
"henegouwen", "hainaut", "hennegau", |
122 |
123 |
"luik", "liège", "lüttich", |
123 |
124 |
"luxemburg", "luxembourg", |
124 |
125 |
"namen", "namur", "namür", |
125 |
126 |
"waals-brabant", "brabant wallon", "wallonisch-brabant", |
126 |
127 |
"brussel", "bruxelles", "brüssel", |
127 |
128 |
]: |
128 |
129 |
context["contact_response"] = _("The province you entered (") + \ |
129 |
130 |
clean_message["provincio"] + _(") was a misspelling, or is not a Belgian province. Message discarded.") |
130 |
131 |
elif "henryquorp" in clean_message["name"].lower(): # Removed the hyperlink detector, since I'm allowing that now. |
131 |
132 |
add_to_bots(request) |
132 |
133 |
else: |
133 |
134 |
# Neutralize possible hyperlinks |
134 |
135 |
neutralized_message = clean_message["message"].replace(".", ". ") |
135 |
136 |
client_ip, _ = get_client_ip(request) |
136 |
137 |
if send_message(clean_message["name"], str(client_ip), neutralized_message): |
137 |
138 |
context["contact_response"] = _("Message sent!") |
+ |
139 |
context["contact_response"] = _("Message sent!") |
138 |
140 |
else: |
139 |
141 |
context["contact_response"] = _("An error occured while trying to send the message. Please try again later.") |
+ |
142 |
context["contact_response"] = _("An error occured while trying to send the message. Please try again later.") |
140 |
143 |
else: # The submitted form data was invalid |
141 |
144 |
context["contact_response"] = _("The submitted form contained invalid data, and was discarded.") |
+ |
145 |
context["contact_response"] = _("The submitted form contained invalid data, and was discarded.") |
142 |
146 |
|
143 |
147 |
|
144 |
148 |
|
145 |
149 |
timezone.activate("Europe/Brussels") |
146 |
150 |
time_string = timezone.localtime(timezone.now()).strftime(" (%H:%M) ") |
147 |
151 |
status = _("Current status/location:") + time_string + get_current_status() |
148 |
- | template = "about/index.djhtml" |
+ |
152 |
template = "about/index.djhtml" |
149 |
153 |
|
150 |
154 |
return render(request, template, context) |
151 |
155 |
|
152 |
156 |
def myself(request): |
153 |
157 |
template = "about/about.djhtml" |
154 |
158 |
|
155 |
159 |
context = { |
156 |
160 |
'subject': _("Myself"), |
157 |
161 |
'navbar_title': _("Myself"), |
158 |
162 |
'age': get_age(), |
159 |
163 |
} |
160 |
164 |
context.update(standard_context()) |
161 |
165 |
return render(request, template, context) |
162 |
166 |
|
163 |
167 |
def project_archive(request): |
164 |
168 |
template = "about/project-archive.djhtml" |
165 |
169 |
context = standard_context() |
166 |
170 |
return render(request, template, context) |
167 |
171 |
|
168 |
172 |
def activism(request): |
169 |
173 |
template = "about/activism.djhtml" |
170 |
174 |
context = standard_context() |
171 |
175 |
return render(request, template, context) |
172 |
176 |
|
173 |
177 |