Fix the time handling for the get_current_status function
Django defaults to UTC, which is not a problem, except for when I want to display the time of where I am, which is Belgium. I could use Python's built in datetime stuff, but it's such a clusterfuck, and Django already provides a decent framework to handle that for me.
What's left now is to move a lot of text to the templates, where they belong, instead of preformatting strings in the view module.
- Author
- Vngngdn
- Date
- Feb. 18, 2017, 4:20 p.m.
- Hash
- dceb96c710ddb17d7e80537c2950454940928dfd
- Parent
- 60df9610f72a89fd8f3b40d31dc7901cf1e641c6
- Modified files
- DEPENDENCIES.md
- views.py
DEPENDENCIES.md ¶
1 addition and 0 deletions.
View changes Hide changes
1 |
1 |
============ |
2 |
2 |
|
3 |
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 |
4 |
|
5 |
5 |
Legend |
6 |
6 |
------ |
7 |
7 |
|
8 |
8 |
The dependencies themselves have been ranked with a certain grade. I explain what they mean here: |
9 |
9 |
|
10 |
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 |
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 |
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 |
13 |
|
14 |
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 |
15 |
|
16 |
16 |
A |
17 |
17 |
- |
18 |
18 |
* [jQuery](https://jquery.com/): Necessary for Materialize to work properly. |
19 |
19 |
* [Materialize](http://materializecss.com/): The layout framework for the web app. (Material Design is the best) |
20 |
20 |
|
21 |
21 |
|
22 |
22 |
B |
23 |
23 |
- |
24 |
24 |
|
+ |
25 |
|
25 |
26 |
C |
26 |
27 |
- |
27 |
28 |
views.py ¶
14 additions and 13 deletions.
View changes Hide changes
1 |
1 |
import datetime |
2 |
- | from datetime import date |
3 |
- | |
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. |
+ |
2 |
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 |
3 |
from django.http import HttpResponseRedirect, HttpResponse # Why? |
6 |
4 |
from django.core.urlresolvers import reverse # Why? |
7 |
5 |
from django.utils.translation import ugettext as _ |
8 |
6 |
from .models import * |
9 |
7 |
|
10 |
8 |
# First, I list some standard variables that are common for most of the sites of this app. |
11 |
9 |
|
12 |
10 |
def get_age(): |
13 |
11 |
"""Returns my current age.""" |
14 |
12 |
today = date.today() |
15 |
13 |
birthday = date(1996, 8, 28) |
16 |
14 |
age = today - birthday |
17 |
15 |
years = str(int(age.days / 365)) |
18 |
16 |
return years |
19 |
17 |
|
20 |
18 |
def footer_description(): |
21 |
19 |
years = get_age() |
22 |
20 |
|
23 |
21 |
""" |
24 |
22 |
Grandpa easter egg: The Dutch version of the most ingenius algorithm I ever wrote: |
25 |
23 |
vandaag = datum.vandaag() |
26 |
24 |
geboortedatum = datum(28-08-1996) |
27 |
25 |
leeftijd = vandaag - geboortedatum |
28 |
26 |
jaren = leeftijd.jaren() |
29 |
27 |
This will help me explain what programming has brought me. =3 |
30 |
28 |
""" |
31 |
29 |
|
32 |
30 |
return "Main pages of Maarten's website, a " + years + " year old Belgian programmer. Also an undergraduate informatics student @ UHasselt." |
33 |
31 |
|
34 |
32 |
def footer_links(): |
35 |
33 |
footer_links = [ |
36 |
34 |
["Contact", "mailto:maarten.vangeneugden@student.uhasselt.be"], |
37 |
35 |
["UHasselt", "https://www.uhasselt.be"], |
38 |
36 |
] |
39 |
37 |
return footer_links |
40 |
38 |
|
41 |
39 |
# TODO: Move this stuff to the template module. This is basically a description |
42 |
40 |
# of HOW to display data, but the view module is only responsible for WHAT data |
43 |
41 |
# to display. |
44 |
42 |
def standard_context(): |
45 |
43 |
context = { |
46 |
44 |
'materialDesign_color': "blue", |
47 |
45 |
'materialDesign_accentColor': "orange", |
48 |
46 |
'navbar_backArrow': True, |
49 |
47 |
'footer_title': "Home pages", |
50 |
48 |
'footer_description': footer_description(), |
51 |
49 |
'footer_links': footer_links(), |
52 |
50 |
} |
53 |
51 |
return context |
54 |
52 |
|
55 |
53 |
def get_current_status( |
56 |
- | day = datetime.datetime.now().weekday(), |
57 |
- | hour = datetime.datetime.now().time().hour, |
58 |
- | minute = datetime.datetime.now().time().minute): |
59 |
- | """Returns a string specifying my current state (and sometimes location). |
+ |
54 |
"""Returns a string specifying my current state (and sometimes location). |
60 |
55 |
|
61 |
56 |
This function is actually based on my weekly schedule. I'd normally hook it |
62 |
57 |
up to my iCal files, but that doesn't include things like sleeping. Not to |
63 |
58 |
mention my university has a hard time following standards like "Put the |
64 |
59 |
location in the location field, not in the title of the appointment". I |
65 |
60 |
figured a simple function would do the job just as well. |
66 |
61 |
|
67 |
62 |
This function is referentially transparent. |
68 |
- | |
69 |
- | Keyword arguments: |
70 |
63 |
day -- The day of the week. 0 is Monday, 6 is Sunday (default today) |
71 |
- | hour -- The hour to check. (default current hour) |
72 |
- | minute -- The minute to check. (default current minute) |
73 |
- | """ |
+ |
64 |
""" |
74 |
65 |
|
75 |
66 |
""" Readable standard schedule of my week (00:00 - 08:00 is always sleep): |
76 |
67 |
Monday: |
77 |
68 |
09:00 - 11:30: Mathematics @ C104 |
78 |
69 |
13:00 - 15:00: Informatics Management @ A101 |
79 |
70 |
Tuesday: |
80 |
71 |
10:00 - 11:30: Computer Graphics @ C105 |
81 |
72 |
13:30 - 15:30: AI @ H1 |
82 |
73 |
Wednesday: Free! |
83 |
74 |
Thursday: |
84 |
75 |
10:00 - 12:00: Software Engineering @ A7 (Temporary; prone to change!) |
85 |
76 |
13:00 - 15:00: Beleidsinformatica @ <variable> |
86 |
77 |
Friday - Sunday: Free! |
87 |
78 |
On free days, the planning is usually this: |
88 |
79 |
14:00 - 19:00: Studying / general work |
89 |
80 |
20:00 - 23:59: Leisure =D |
90 |
81 |
""" |
91 |
82 |
|
92 |
83 |
""" Note on usage of the range() function: |
+ |
84 |
timezone.activate("Europe/Brussels") |
+ |
85 |
dt = timezone.localtime(timezone.now()) |
+ |
86 |
|
+ |
87 |
day = dt.weekday() |
+ |
88 |
hour = dt.time().hour |
+ |
89 |
print(hour) |
+ |
90 |
minute = dt.time().minute |
+ |
91 |
|
+ |
92 |
""" Note on usage of the range() function: |
93 |
93 |
range(x, y) returns a list, beginning from x, but excluding y. So if a |
94 |
94 |
course runs from 13:00 to 15:00, then y should still be 15. Why? Because |
95 |
95 |
that makes it so that 14:59 is included, but 15:00 is not. if y would be 16, |
96 |
96 |
then 15:30 would also be included. |
97 |
97 |
""" |
98 |
98 |
|
99 |
99 |
if day == 0: # Monday |
100 |
100 |
if hour in [9, 10] or (hour == 11 and minute <= 30): |
101 |
101 |
return _("Studying Mathematics @ C104. See you around noon!") |
102 |
102 |
if hour in range(13, 15): |
103 |
103 |
return _("Following college: Informatics Management @ A101.") |
104 |
104 |
if day == 1: # Tuesday |
105 |
105 |
if hour == 10 or (hour == 11 and minute <= 30): |
106 |
106 |
return _("Studying Computer Graphics @ C105. Back in C24 at noon!") |
107 |
107 |
if (hour == 13 and minute >= 30) or \ |
108 |
108 |
(hour == 14) or \ |
109 |
109 |
(hour == 15 and minute < 30): |
110 |
110 |
return _("Trying to understand Artificial Intelligence @ H1...") |
111 |
111 |
if day == 3: # Thursday |
112 |
112 |
if hour in range(10, 12): |
113 |
113 |
return _("Engineering the Software @ A7. Tough nut to crack...") |
114 |
114 |
if hour in range(13, 15): |
115 |
115 |
return _("Fighting boredom of Informatics Management. Looking \ |
116 |
116 |
forward to the weekend!") |
117 |
117 |
|
118 |
118 |
# General answers that span over multiple days |
119 |
119 |
# They may overlap with previous tests, but that means they fill in gaps |
120 |
120 |
# like study time |
121 |
121 |
if hour <= 8: |
122 |
122 |
return _("I'm asleep. See you tomorrow! =D") |
123 |
123 |
if day in [0, 1, 3]: |
124 |
124 |
if hour == 12: |
125 |
125 |
return _("Having lunch in C24. I'm available if you need me!") |
126 |
126 |
elif hour in range(9, 18): |
127 |
127 |
return _("At UHasselt! Studying in C24. Come by for a chat, or email me!") |
128 |
128 |
if day in [2, 4, 5, 6]: |
129 |
129 |
if hour in range(13, 19): |
130 |
130 |
return _("Studying from home, or other work. Perhaps I'll see you in the evening?") |
131 |
131 |
elif hour in range(19, 24): |
132 |
132 |
return _("Relaxing, and enjoying my free time. Feel free to talk! 😃") |
133 |
133 |
|
134 |
134 |
# If nothing's returned by now, return a general response |
135 |
135 |
return _("Probably chilling a bit. Feel free to talk! ❤") |
136 |
136 |
|
137 |
137 |
# Views: |
138 |
138 |
|
139 |
139 |
def index(request): |
140 |
140 |
time_string = datetime.now().strftime(" (%H:%M) ") |
141 |
- | status = _("Current status/location:") + time_string + get_current_status() |
+ |
141 |
time_string = timezone.localtime(timezone.now()).strftime(" (%H:%M) ") |
+ |
142 |
status = _("Current status/location:") + time_string + get_current_status() |
142 |
143 |
template = "about/index.html" |
143 |
144 |
|
144 |
145 |
cards = Card.objects.order_by('?') # The '?' indicates the objects must be ordered randomly. |
145 |
146 |
quotes = Quote.objects.all() |
146 |
147 |
randomQuote = random.choice(quotes) |
147 |
148 |
|
148 |
149 |
largeSizes = [] |
149 |
150 |
mediumSizes = [] |
150 |
151 |
for i in range(0, len(cards)): |
151 |
152 |
newLargeSizes = [6, 4, 2] |
152 |
153 |
newMediumSizes = [8, 4] |
153 |
154 |
random.shuffle(newLargeSizes) |
154 |
155 |
random.shuffle(newMediumSizes) |
155 |
156 |
largeSizes.extend(newLargeSizes) |
156 |
157 |
mediumSizes.extend(newMediumSizes) |
157 |
158 |
|
158 |
159 |
contextList = [] |
159 |
160 |
i = 0 |
160 |
161 |
for card in cards: |
161 |
162 |
contextList.append([card, mediumSizes[i], largeSizes[i]]) |
162 |
163 |
i += 1 |
163 |
164 |
|
164 |
165 |
# TODO: Move this stuff to the template module. This is basically a description |
165 |
166 |
# of HOW to display data, but the view module is only responsible for WHAT data |
166 |
167 |
# to display. |
167 |
168 |
context = { |
168 |
169 |
'status': status, |
169 |
170 |
'materialDesign_color': "blue", |
170 |
171 |
'materialDesign_accentColor': "orange", |
171 |
172 |
'navbar_title': "Maarten's website", |
172 |
173 |
'navbar_fixed': False, |
173 |
174 |
'parallax_src': "/media/about/images/parallax.png", |
174 |
175 |
'footer_title': "Home pages", |
175 |
176 |
'footer_description': footer_description, |
176 |
177 |
'footer_links': footer_links, |
177 |
178 |
'cards': contextList, |
178 |
179 |
'quote': randomQuote, |
179 |
180 |
} |
180 |
181 |
|
181 |
182 |
return render(request, template, context) |
182 |
183 |
|
183 |
184 |
def myself(request): |
184 |
185 |
template = "about/about.html" |
185 |
186 |
|
186 |
187 |
context = { |
187 |
188 |
'subject': "Myself", |
188 |
189 |
'navbar_title': "Myself", |
189 |
190 |
'age': get_age(), |
190 |
191 |
} |
191 |
192 |
context.update(standard_context()) |
192 |
193 |
return render(request, template, context) |
193 |
194 |
|
194 |
195 |
def principles(request): |
195 |
196 |
template = "about/principles.html" |
196 |
197 |
|
197 |
198 |
data = Principle.objects.order_by('title') |
198 |
199 |
|
199 |
200 |
context = { |
200 |
201 |
'subject': "principles", |
201 |
202 |
'navbar_title': "Principles", |
202 |
203 |
'data': data, |
203 |
204 |
} |
204 |
205 |
context.update(standard_context()) |
205 |
206 |
return render(request, template, context) |
206 |
207 |
|
207 |
208 |
def hacking(request): |
208 |
209 |
template = "about/hacking.html" |
209 |
210 |
|
210 |
211 |
data = Hack.objects.order_by('title') |
211 |
212 |
|
212 |
213 |
context = { |
213 |
214 |
'subject': "hacking", |
214 |
215 |
'navbar_title': "Hacking", |
215 |
216 |
'data': data, |
216 |
217 |
} |
217 |
218 |
context.update(standard_context()) |
218 |
219 |
return render(request, template, context) |
219 |
220 |
|
220 |
221 |
def me(request): |
221 |
222 |
template = "about/me.html" |
222 |
223 |
|
223 |
224 |
data = AboutMe.objects.order_by('title') |
224 |
225 |
|
225 |
226 |
context = { |
226 |
227 |
'subject': "me", |
227 |
228 |
'navbar_title': "Me", |
228 |
229 |
'data': data, |
229 |
230 |
} |
230 |
231 |
context.update(standard_context()) |
231 |
232 |
return render(request, template, context) |
232 |
233 |
|
233 |
234 |
def webstack(request): |
234 |
235 |
template = "about/webstack.html" |
235 |
236 |
|
236 |
237 |
data = Stack.objects.order_by('title') |
237 |
238 |
|
238 |
239 |
context = { |
239 |
240 |
'subject': "web stack", |
240 |
241 |
'navbar_title': "Web stack", |
241 |
242 |
'data': data, |
242 |
243 |
} |
243 |
244 |
context.update(standard_context()) |
244 |
245 |
return render(request, template, context) |
245 |
246 |
|
246 |
247 |
def software(request): |
247 |
248 |
template = "about/software.html" |
248 |
249 |
|
249 |
250 |
data = Program.objects.order_by('title') |
250 |
251 |
|
251 |
252 |
context = { |
252 |
253 |
'subject': "software", |
253 |
254 |
'navbar_title': "Software", |
254 |
255 |
'data': data, |
255 |
256 |
} |
256 |
257 |
context.update(standard_context()) |
257 |
258 |
return render(request, template, context) |
258 |
259 |
# WARNING: |
259 |
260 |
# 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! |
260 |
261 |
|
261 |
262 |
def security(request): |
262 |
263 |
template = "about/security.html" |
263 |
264 |
|
264 |
265 |
data = SecurityMeasure.objects.order_by('title') |
265 |
266 |
|
266 |
267 |
context = { |
267 |
268 |
'subject': "security", |
268 |
269 |
'navbar_title': "Security", |
269 |
270 |
'data': data, |
270 |
271 |
} |
271 |
272 |
context.update(standard_context()) |
272 |
273 |
return render(request, template, context) |
273 |
274 |
|
274 |
275 |
def roadmap(request): |
275 |
276 |
template = "about/roadmap.html" |
276 |
277 |
|
277 |
278 |
data = Goal.objects.order_by('title') |
278 |
279 |
|
279 |
280 |
context = { |
280 |
281 |
'subject': "roadmap", |
281 |
282 |
'navbar_title': "Roadmap", |
282 |
283 |
'data': data, |
283 |
284 |
} |
284 |
285 |
context.update(standard_context()) |
285 |
286 |
return render(request, template, context) |
286 |
287 |
|
287 |
288 |