home

Finish new bot checker

Author
Maarten Vangeneugden
Date
April 18, 2021, 10:55 p.m.
Hash
afa89304c5af9624e6d1032158671f1b1225fef3
Parent
22d6c6d00ee1fbbb53dbe4efb36bea908ad014f6
Modified files
templates/about/main_content.djhtml
views.py

templates/about/main_content.djhtml

3 additions and 1 deletion.

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
<!--
103
103
<section>
104
104
    <h2>{% translate "" %}
105
-
-->
106
105
<section>
107
106
    <h2>{% translate "Contact me" %}</h2>
108
107
    <p>{% blocktranslate %}If you wish to contact me, use this convenient form,
109
108
        the most direct link to yours truly. Leave me a thank you note, tell me
110
109
        something important, or correct a typo I made, it's all good, I love to
111
110
        hear from you!
112
111
        If necessary, put some contact info of yourself in your message so I can get
113
112
        back to you. Do <em>not</em> put a hyperlink in your message. Adding a
114
113
        hyperlink will put automatically ban your computer from my website
115
114
        and probably make it explode, so don't do that.{% endblocktranslate %}</p>
116
115
    <form action="" method="post">
117
116
        {% csrf_token %}
118
117
        <input type="text" name="name" mozactionhint="send" enterkeyhint="send" maxlength="64" placeholder="{% translate "Your name" %}" required>
119
118
        <br>
120
119
        <textarea maxlength="2000" spellcheck="true" name="message" required></textarea>
121
120
        <br>
122
121
        <input type="submit" value="✉️ {% translate "Send" %}">
+
122
        one of the three Belgian languages:{% endblocktranslate %}</p>
+
123
        <input type="text" name="provincio" mozactionhint="send" enterkeyhint="send" maxlength="64" placeholder="{% translate "Province" %}" required>
+
124
        <input type="submit" value="✉️ {% translate "Send" %}">
123
125
    </form>
124
126
</section>
125
127

views.py

6 additions and 5 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
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, message):
85
-
    """ Sends a message to me if the visitor submits one on my website. """
+
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 + " 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
108
    context = standard_context()
109
109
    # First, handle possible contact
110
110
    if request.method == "POST":  # Message received
111
111
        form = MessageForm(request.POST)
112
112
        if form.is_valid():
113
113
            clean_message = form.cleaned_data
114
114
            # Bot test:
115
115
            if clean_message["provincio"].lower() not in [
116
116
                    "limburg", "limbourg",
117
117
                    "antwerpen", "anvers", "antorf", "antorff",
118
118
                    "vlaams-brabant", "brabant flamand", "flämisch-brabant",
119
119
                    "oost-vlaanderen", "flandre-orientale", "ostflandern", 
120
120
                    "west-vlaanderen", "flandre-occidentale", "westflandern",
121
121
                    "henegouwen", "hainaut", "hennegau",
122
122
                    "luik", "liège", "lüttich",
123
123
                    "luxemburg", "luxembourg",
124
124
                    "namen", "namur", "namür",
125
125
                    "waals-brabant", "brabant wallon", "wallonisch-brabant",
126
126
                    "brussel", "bruxelles", "brüssel",
127
127
                    ]:
128
128
                context["contact_response"] = _("The submitted form contained invalid data, and was discarded.")
129
-
            elif "henryquorp" in clean_message["name"].lower() or contains_hyperlink(clean_message["message"]):
130
-
                add_to_bots(request)
+
129
                clean_message["provincio"] + _(") was a misspelling, or is not a Belgian province. Message discarded.")
+
130
            elif "henryquorp" in clean_message["name"].lower():  # Removed the hyperlink detector, since I'm allowing that now. 
+
131
                add_to_bots(request)
131
132
            else:
132
133
                # Neutralize possible hyperlinks
133
134
                neutralized_message = clean_message["message"].replace(".", ".   ")
134
135
                client_ip, _ = get_client_ip(request)
135
136
                if send_message(clean_message["name"] + " | " + str(client_ip), neutralized_message):
136
-
                    context["contact_response"] = _("Message sent!")
+
137
                    context["contact_response"] = _("Message sent!")
137
138
                else:
138
139
                    context["contact_response"] = _("An error occured while trying to send the message. Please try again later.")
139
140
        else:  # The submitted form data was invalid
140
141
            context["contact_response"] = _("The submitted form contained invalid data, and was discarded.")
141
142
        
142
143
143
144
    
144
145
    timezone.activate("Europe/Brussels")
145
146
    time_string = timezone.localtime(timezone.now()).strftime(" (%H:%M) ")
146
147
    status = _("Current status/location:") + time_string + get_current_status()
147
148
    template = "about/index.djhtml"
148
149
149
150
    return render(request, template, context)
150
151
151
152
def myself(request):
152
153
    template = "about/about.djhtml"
153
154
154
155
    context = {
155
156
            'subject': _("Myself"),
156
157
            'navbar_title': _("Myself"),
157
158
            'age': get_age(),
158
159
            }
159
160
    context.update(standard_context())
160
161
    return render(request, template, context)
161
162
162
163
def project_archive(request):
163
164
    template = "about/project-archive.djhtml"
164
165
    context = standard_context()
165
166
    return render(request, template, context)
166
167
167
168
def activism(request):
168
169
    template = "about/activism.djhtml"
169
170
    context = standard_context()
170
171
    return render(request, template, context)
171
172
    
172
173