home

Add the base files of my main home pages

Author
Vngngdn
Date
Feb. 18, 2017, 2:32 p.m.
Hash
8e44d6914181b48a9b71829de274252c9849f1eb
Parents
Modified files
DEPENDENCIES.md
__init__.py
admin.py
apps.py
models.py
tests.py
urls.py
views.py

DEPENDENCIES.md

27 additions and 0 deletions.

View changes Hide changes
+
1
============
+
2
+
3
Since web apps (and everything web related) are known to suck at dependency handling (which is why we have Bower, NPM, cdnjs, docker, ... (I'll explain sometime somewhere why this is done, and why it's useless)), I've decided to take matters in my own hands; I'll just provide one simple markdown file listing all dependencies in human-readable format. I don't care whether this helps or not, but no harm is done, right?
+
4
+
5
Legend
+
6
------
+
7
+
8
The dependencies themselves have been ranked with a certain grade. I explain what they mean here:
+
9
+
10
 * A : This dependency is present inside the app. This will be in the form of ready-to-use source code files. As such, they need no further attention.
+
11
 * B : This dependency is present inside the app, or very easy to retrieve yourself. This will be in the form of an archive file (i.e. .tar.gz), OR this needs additional work to function properly. In these cases, I refer to their documentation which will be available at the location of the files.
+
12
 * C : This dependency does not come with the app, and requires manual effort to set up. These are often system packages, which often means (if you're on GNU/Linux) to search for it in your repositories. Their documentation is your last resort for these if it doesn't work as it should.
+
13
 
+
14
I hope I never will, but when it's necessary, I'll add a D grade, for unreadable, egregious bogus software that will give you all horrible kinds of diseases if you dare to work with it, but are indispensable to make the web app function. Just be happy I don't use it yet. (For example, PHP qualifies as D, so praise [our lord and saviour](https://rms.sexy) I write Python.)
+
15
+
16
A
+
17
-
+
18
 * [jQuery](https://jquery.com/): Necessary for Materialize to work properly.
+
19
 * [Materialize](http://materializecss.com/): The layout framework for the web app. (Material Design is the best)
+
20
+
21
+
22
B
+
23
-
+
24
+
25
C
+
26
-
+
27

__init__.py

0 additions and 0 deletions.

View changes Hide changes

admin.py

16 additions and 0 deletions.

View changes Hide changes
+
1
+
2
+
3
from .models import *
+
4
+
5
# Down here, all models are registered, making them suitable for administration (In essence; making them pop up in the admin interface).
+
6
+
7
admin.site.register(Card)
+
8
admin.site.register(Principle)
+
9
admin.site.register(Program)
+
10
admin.site.register(Stack)
+
11
admin.site.register(Quote)
+
12
admin.site.register(Hack)
+
13
admin.site.register(AboutMe)
+
14
admin.site.register(SecurityMeasure)
+
15
admin.site.register(Goal)
+
16

apps.py

5 additions and 0 deletions.

View changes Hide changes
+
1
+
2
+
3
class WinkellijstConfig(AppConfig):
+
4
    name = 'about'
+
5

models.py

85 additions and 0 deletions.

View changes Hide changes
+
1
+
2
# Cards: Describes a card that will be loaded in the main page, providing links to useful information and other apps.
+
3
class Card(models.Model):
+
4
    title = models.CharField(max_length=20) # 20 should sustain well.
+
5
    description = models.CharField(max_length=256) # 256 as well.
+
6
    link1 = models.CharField('First link', blank=True, max_length=50) # I could make this a URLField, but that doesn't accept cases like "/ITdays".
+
7
    linkName1 = models.CharField('Name of first link', blank=True, max_length=20)
+
8
    link2 = models.CharField('Second link', blank=True, max_length=50) # This may be empty.
+
9
    linkName2 = models.CharField('Name of second link', blank=True, max_length=20) # This too.
+
10
    image = models.ImageField(upload_to='about/images/cards', blank=True) # Sometimes the cards should get an image.
+
11
    
+
12
    def __str__(self):
+
13
        return self.title
+
14
+
15
# What you're about to see, is a very rare case of where multi-level inheritance
+
16
# is actually done correctly. Notes should be taken. (Also worth mentioning
+
17
# Django is so well built it actually makes this possible.)
+
18
+
19
# First, it should be said all objects have an extremely similar structure. That
+
20
# doesn't qualify them yet for multilevel inheritance, but it's a good sign.
+
21
+
22
# Also, note how Card, even though it has both title and description, is NOT
+
23
# inherited from this base class. This is deliberate; Card is not an object with
+
24
# a comparable behavior, and thus, differs too much as an object to derive from
+
25
# this one.
+
26
class Subject(models.Model):
+
27
    """ This class should not be instantiated. Look at it as being an abstract
+
28
    class. """
+
29
+
30
    title = models.CharField(max_length=50)
+
31
    description = models.TextField()
+
32
+
33
    def __str__(self):
+
34
        return self.title
+
35
+
36
    """ This Meta is important, because it tells Django that Subject is
+
37
    'abstract', in that it just has some fields that should be passed to its
+
38
    children. """
+
39
    class Meta:
+
40
        abstract = True
+
41
# Now you may say: Well, some subjects have links, why not make another object,
+
42
# and use it for just that? Well, because that would imply multiple inheritance,
+
43
# which is not necessary here*, and (if that second object would inherit Model
+
44
# again) cause a diamond inheritance.
+
45
# *Most of the time people use inheritance because it's convenient. While that
+
46
# may be a reason, it shouldn't be the only reason for it. Inheritance is not
+
47
# made to make programming convenient, that's what programming languages are
+
48
# for. Inheritance is to inherit behavior from another object. And since that's
+
49
# my goal here, inheritance is a passable programming decision.
+
50
# Also, I'm referring here to OOP inheritance, which means "inheriting state AND
+
51
# behavior". Languages that implement other paradigms can also have inheritance.
+
52
# Clojure, for example, is not OOP, but fully functional, and its inheritance
+
53
# capabilities are WAY better.
+
54
+
55
class Principle(Subject):
+
56
    pass
+
57
class AboutMe(Subject):
+
58
    pass
+
59
class Program(Subject):
+
60
    link = models.URLField()
+
61
class Stack(Subject):
+
62
    link = models.URLField()
+
63
class Hack(Subject):
+
64
    pass
+
65
class SecurityMeasure(Subject):
+
66
    pass
+
67
class Goal(Subject):
+
68
    pass
+
69
+
70
# A last pick on inheritance (I feel so obliged to defend my decision because I
+
71
# decided to use inheritance, apologies if you're sick of taking notes):
+
72
# Note that I could've easily solved this problem without inheritance. Some
+
73
# objects even lack any other variable or function of some sort.
+
74
# But also, note how easy it now becomes to edit all those objects at once: If I
+
75
# want to increase the length (And yes, that length should be the same, I like
+
76
# that), I can now do that all at once. THIS is when inheritance can be a good
+
77
# thing: To increase code maintainability for a lot of different objects.
+
78
+
79
class Quote(models.Model):
+
80
    text = models.TextField()
+
81
    author = models.CharField(max_length=256)
+
82
    link = models.URLField(blank=True)
+
83
+
84
# Really, these max_lengths... Sometimes I look at my code and just think what an arbitrary asshole I can be to my database.
+
85

tests.py

3 additions and 0 deletions.

View changes Hide changes
+
1
+
2
# Create your tests here.
+
3

urls.py

15 additions and 0 deletions.

View changes Hide changes
+
1
+
2
from . import views # Imports the views from the same directory (which is views.py).
+
3
+
4
urlpatterns = [
+
5
        url(r'^$', views.index, name='about-index'),
+
6
        url(r'^myself$', views.myself, name='main-myself'),
+
7
        url(r'^principles$', views.principles, name='about-principles'),
+
8
        url(r'^hacking$', views.hacking, name='about-hacking'),
+
9
        url(r'^me$', views.me, name='about-me'),
+
10
        url(r'^webstack$', views.webstack, name='about-webstack'),
+
11
        url(r'^software$', views.software, name='about-software'),
+
12
        url(r'^security$', views.security, name='about-security'),
+
13
        url(r'^roadmap$', views.roadmap, name='about-roadmap'),
+
14
        ]
+
15

views.py

236 additions and 0 deletions.

View changes Hide changes
+
1
from datetime import date
+
2
+
3
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.
+
4
from django.http import HttpResponseRedirect, HttpResponse # Why?
+
5
from django.core.urlresolvers import reverse # Why?
+
6
from django.utils.translation import ugettext as _
+
7
from .models import *
+
8
+
9
# First, I list some standard variables that are common for most of the sites of this app.
+
10
+
11
def get_age():
+
12
    """Returns my current age."""
+
13
    today = date.today()
+
14
    birthday = date(1996, 8, 28)
+
15
    age = today - birthday
+
16
    years = str(int(age.days / 365))
+
17
    return years
+
18
+
19
def footer_description():
+
20
    years = get_age()
+
21
+
22
    """
+
23
    Grandpa easter egg: The Dutch version of the most ingenius algorithm I ever wrote:
+
24
    vandaag = datum.vandaag()
+
25
    geboortedatum = datum(28-08-1996)
+
26
    leeftijd = vandaag - geboortedatum
+
27
    jaren = leeftijd.jaren()
+
28
    This will help me explain what programming has brought me. =3
+
29
    """
+
30
+
31
    return "Main pages of Maarten's website, a " + years + " year old Belgian programmer. Also an undergraduate informatics student @ UHasselt."
+
32
+
33
def footer_links():
+
34
    footer_links = [
+
35
            ["Contact", "mailto:maarten.vangeneugden@student.uhasselt.be"],
+
36
            ["UHasselt", "https://www.uhasselt.be"],
+
37
            ]
+
38
    return footer_links
+
39
+
40
# TODO: Move this stuff to the template module. This is basically a description
+
41
# of HOW to display data, but the view module is only responsible for WHAT data
+
42
# to display.
+
43
def standard_context():
+
44
    context = {
+
45
            'materialDesign_color': "blue",
+
46
            'materialDesign_accentColor': "orange",
+
47
            'navbar_backArrow': True,
+
48
            'footer_title': "Home pages",
+
49
            'footer_description': footer_description(),
+
50
            'footer_links': footer_links(),
+
51
            }
+
52
    return context
+
53
+
54
def get_current_status():
+
55
    """Returns a string specifying my current state.
+
56
+
57
    This function is actually based on my weekly schedule. I'd normally hook it
+
58
    up to my iCal files, but that doesn't include things like sleeping. I
+
59
    figured a simple function would do the job just as well.
+
60
    """
+
61
    import datetime
+
62
    current_date = datetime.datetime.now()
+
63
    current_time = current_date.time()
+
64
    status = _("Current status/location: ")
+
65
    if current_time.hour <= 8:  # 00:00 - 08:00
+
66
        status = status + _("I'm asleep. See you tomorrow! =D")
+
67
    elif current_time.hour > 8 and current_time.hour <= 17: # 09:00 - 17:00
+
68
        if current_date.weekday() >= 5:  # Saturday (5) or Sunday (6)
+
69
            if current_time.hour == 13:
+
70
                status = status + _("Watching the news, or eating something delicious...")
+
71
            else:
+
72
                status = status + _("Studying from home, so not really available now. Maybe in a couple of hours...")
+
73
        else:  # Midweek
+
74
            if current_time.hour < 11:
+
75
                status = status + _("Attending classes. See you later!")
+
76
            elif current_time.hour == 11 or current_time.hour == 12:
+
77
                status = status + _("Lunch @ UHasselt. I'm available if you need me! <3")
+
78
            else:
+
79
                status = status + _("Studying at university! Send me a mail, or visit me in C23!")
+
80
    else:
+
81
        status = status + _("At home, relaxing a bit. Feel free to talk! =D")
+
82
+
83
    return status
+
84
+
85
# Views:
+
86
+
87
def index(request):
+
88
+
89
+
90
    status = get_current_status()
+
91
    template = "about/index.html"
+
92
+
93
    cards = Card.objects.order_by('?') # The '?' indicates the objects must be ordered randomly.
+
94
    quotes = Quote.objects.all()
+
95
    randomQuote = random.choice(quotes)
+
96
+
97
    largeSizes = []
+
98
    mediumSizes = []
+
99
    for i in range(0, len(cards)):
+
100
        newLargeSizes = [6, 4, 2]
+
101
        newMediumSizes = [8, 4]
+
102
        random.shuffle(newLargeSizes)
+
103
        random.shuffle(newMediumSizes)
+
104
        largeSizes.extend(newLargeSizes)
+
105
        mediumSizes.extend(newMediumSizes)
+
106
+
107
    contextList = []
+
108
    i = 0
+
109
    for card in cards:
+
110
        contextList.append([card, mediumSizes[i], largeSizes[i]])
+
111
        i += 1
+
112
+
113
    # TODO: Move this stuff to the template module. This is basically a description
+
114
    # of HOW to display data, but the view module is only responsible for WHAT data
+
115
    # to display.
+
116
    context = {
+
117
            'status': status,
+
118
            'materialDesign_color': "blue",
+
119
            'materialDesign_accentColor': "orange",
+
120
            'navbar_title': "Maarten's website",
+
121
            'navbar_fixed': False,
+
122
            'parallax_src': "/media/about/images/parallax.png",
+
123
            'footer_title': "Home pages",
+
124
            'footer_description': footer_description,
+
125
            'footer_links': footer_links,
+
126
            'cards': contextList,
+
127
            'quote': randomQuote,
+
128
            }
+
129
+
130
    return render(request, template, context)
+
131
+
132
def myself(request):
+
133
    template = "about/about.html"
+
134
 
+
135
    context = {
+
136
            'subject': "Myself",
+
137
            'navbar_title': "Myself",
+
138
            'age': get_age(),
+
139
            }
+
140
    context.update(standard_context())
+
141
    return render(request, template, context)
+
142
+
143
def principles(request):
+
144
    template = "about/principles.html"
+
145
 
+
146
    data = Principle.objects.order_by('title')
+
147
+
148
    context = {
+
149
            'subject': "principles",
+
150
            'navbar_title': "Principles",
+
151
            'data': data,
+
152
            }
+
153
    context.update(standard_context())
+
154
    return render(request, template, context)
+
155
    
+
156
def hacking(request):
+
157
    template = "about/hacking.html"
+
158
 
+
159
    data = Hack.objects.order_by('title')
+
160
+
161
    context = {
+
162
            'subject': "hacking",
+
163
            'navbar_title': "Hacking",
+
164
            'data': data,
+
165
            }
+
166
    context.update(standard_context())
+
167
    return render(request, template, context)
+
168
    
+
169
def me(request):
+
170
    template = "about/me.html"
+
171
+
172
    data = AboutMe.objects.order_by('title')
+
173
+
174
    context = {
+
175
            'subject': "me",
+
176
            'navbar_title': "Me",
+
177
            'data': data,
+
178
            }
+
179
    context.update(standard_context())
+
180
    return render(request, template, context)
+
181
+
182
def webstack(request):
+
183
    template = "about/webstack.html"
+
184
 
+
185
    data = Stack.objects.order_by('title')
+
186
+
187
    context = {
+
188
            'subject': "web stack",
+
189
            'navbar_title': "Web stack",
+
190
            'data': data,
+
191
            }
+
192
    context.update(standard_context())
+
193
    return render(request, template, context)
+
194
    
+
195
def software(request):
+
196
    template = "about/software.html"
+
197
 
+
198
    data = Program.objects.order_by('title')
+
199
+
200
    context = {
+
201
            'subject': "software",
+
202
            'navbar_title': "Software",
+
203
            'data': data,
+
204
            }
+
205
    context.update(standard_context())
+
206
    return render(request, template, context)
+
207
    # WARNING:
+
208
    # Because I haven't been able to figure out yet how to add colors to hyperlinks, I put them hardcoded in the database. IF YOU FIND A WAY TO DO IT RIGHT, DO SO ASAP!
+
209
+
210
def security(request):
+
211
    template = "about/security.html"
+
212
 
+
213
    data = SecurityMeasure.objects.order_by('title')
+
214
+
215
    context = {
+
216
            'subject': "security",
+
217
            'navbar_title': "Security",
+
218
            'data': data,
+
219
            }
+
220
    context.update(standard_context())
+
221
    return render(request, template, context)
+
222
 
+
223
def roadmap(request):
+
224
    template = "about/roadmap.html"
+
225
 
+
226
    data = Goal.objects.order_by('title')
+
227
+
228
    context = {
+
229
            'subject': "roadmap",
+
230
            'navbar_title': "Roadmap",
+
231
            'data': data,
+
232
            }
+
233
    context.update(standard_context())
+
234
    return render(request, template, context)
+
235
 
+
236