joeni

Lot of changes to thesis and add bus module

Author
Maarten Vangeneugden
Date
Aug. 22, 2018, 10:33 p.m.
Hash
30d7e2a1ac283b2789d938f219e1ff66905fcdb9
Parent
a4f6a463f4956f9ab4e463cad3d34bc7e7a98dc0
Modified files
administration/bus.py
administration/templates/administration/buses.djhtml
administration/urls.py
administration/views.py
docs/TODO.org
docs/thesis/beveiliging.org
docs/thesis/blackboard.org
docs/thesis/dankwoord.org
docs/thesis/databank.joeni.org
docs/thesis/huisstijl.org
docs/thesis/implementatie_uhasselt.org
docs/thesis/info-processen.org
docs/thesis/lokaalreservaties.org
docs/thesis/master.org
docs/thesis/rooster.joeni.org
docs/thesis/softwarekeuzes.org
docs/thesis/sources.bib
docs/thesis/toekomst.org
docs/thesis/uurroosters.org
docs/thesis/verbeteringspunten_joeni.org
joeni/settings.py
joeni/templates/joeni/header.djhtml
static/css/global.scss
static/css/stylesheet.scss
static/css/tables.scss

administration/bus.py

53 additions and 0 deletions.

View changes Hide changes
+
1
import json
+
2
import requests
+
3
from datetime import datetime, tzinfo
+
4
+
5
def arrivals(stops):
+
6
    """ Returns the a list of buses that stop at the given stops.
+
7
    The buses are in a list, with dicts with the following keys:
+
8
    - number :: The line number of the bus
+
9
    - color :: The hex color to display for this bus line
+
10
    - destination :: The name of the destination (already formatted properly
+
11
    - time :: The datetime of the departure
+
12
    - via :: If the bus does a detour, the name is stored here
+
13
    The list can have a maximum of 20 entries.
+
14
    The subroutine throws an exception if no stops were given.
+
15
    """
+
16
    stops_string = stops.pop(0)  # This returns an error in an empty list, which is supposed to happen if no stops are sent
+
17
    while len(stops) != 0:
+
18
        stops_string = stops_string + "+" + stops.pop(0)
+
19
    received_json_data = requests.get('https://www.delijn.be/rise-api-core/haltes/Multivertrekken/'+stops_string+'/20').json()
+
20
    buses = list()
+
21
    for bus_json in received_json_data["lijnen"]:
+
22
        bus = dict()
+
23
        # Some destinations should be a little bit more descriptive, they're handled here hardcoded
+
24
        destination = bus_json["bestemming"]
+
25
        if destination in ["Hasselt", "Genk", "Neerpelt", "Tongeren", "Maastricht", "Bilzen", "Diepenbeek"]:
+
26
            destination += " Station"
+
27
        bus["destination"] = destination
+
28
        bus["number"] = bus_json["lijnNummerPubliek"]
+
29
        bus["color"] = bus_json["kleurAchterGrond"]
+
30
        unix_time = str(bus_json["vertrekCalendar"])[:10]  # De Lijn API returns too many trailing zeros
+
31
        bus["time"] = datetime.fromtimestamp(int(unix_time))
+
32
        # About via:
+
33
        # The viaBestemming has an annoying tendency to uppercase all destinations.
+
34
        # Some can be hardcoded to the right destination, others just need to be
+
35
        # properly capitalized.
+
36
        via = bus_json["viaBestemming"]
+
37
        if via is not None:
+
38
            if via == "GENK":
+
39
                via = "Genk Station"
+
40
            elif via == "MM VILL & GENK":
+
41
                via = "Genk Station en Maasmechelen Village"
+
42
            elif via == "UNIVERSITEIT":
+
43
                via = "Universiteit Hasselt"
+
44
            elif via == "HASSELT":
+
45
                via = "Hasselt station"
+
46
            elif via == "PATERSPLEIN":
+
47
                via = "Diepenbeek Patersplein"
+
48
            else:
+
49
                via = via.title()  # If it's anything else just capitalize and hope for the best
+
50
            bus["via"] = via
+
51
        buses.append(bus)
+
52
    return buses
+
53

administration/templates/administration/buses.djhtml

57 additions and 0 deletions.

View changes Hide changes
+
1
{% load i18n %}
+
2
{% load humanize %}
+
3
{% load joeni_org %}
+
4
+
5
{% block title %}
+
6
    {% trans "Buses" %} | {{ block.super }}
+
7
{% endblock %}
+
8
+
9
{% block main %}
+
10
    <h1>{% trans "Bus departures" %}</h1>
+
11
    <h2 id="diepenbeek">Campus Diepenbeek</h2>
+
12
    <div class="flex-container">
+
13
    {% for bus in departures_diepenbeek %}
+
14
    <div class="flex-items timetable" style="border-color: {{ bus.color }};">
+
15
        <span class="number" style="background-color: {{ bus.color }};">
+
16
            {{ bus.number }}</span>
+
17
        {{ bus.time|time }}
+
18
        <span style="color: {{ bus.color }}; font-weight:bold;">🡺</span>
+
19
        {{ bus.destination }}
+
20
        <div class="timetable-under">
+
21
        <time>{{ bus.time|naturaltime|capfirst }}</time>
+
22
        {% if bus.via %}
+
23
            <span class="undernote">| Gaat via {{ bus.via }}</span>
+
24
        {% endif %}
+
25
        </div>
+
26
    </div>
+
27
    {% empty %}
+
28
    {% trans "There are currently no buses that stop here." %}
+
29
    {% endfor %}
+
30
    </div>
+
31
+
32
    <h2 id="hasselt">Campus Hasselt (Dusartplein)</h2>
+
33
    <div class="flex-container">
+
34
    {% for bus in departures_dusart %}
+
35
    <div class="flex-items timetable" style="border-color: {{ bus.color }};">
+
36
        <span class="number" style="background-color: {{ bus.color }};">
+
37
            {{ bus.number }}</span>
+
38
        {{ bus.time|time }}
+
39
        <span style="color: {{ bus.color }}; font-weight:bold;">🡺</span>
+
40
        {{ bus.destination }}
+
41
        <div class="timetable-under">
+
42
        <time>{{ bus.time|naturaltime|capfirst }}</time>
+
43
        {% if bus.via %}
+
44
            <span style="color: {{ bus.color }}; font-weight:bold;">|</span>
+
45
            <span class="undernote"> Gaat via {{ bus.via }}</span>
+
46
        {% endif %}
+
47
        </div>
+
48
    </div>
+
49
    {% empty %}
+
50
    {% trans "There are currently no buses that stop here." %}
+
51
    {% endfor %}
+
52
    </div>
+
53
+
54
+
55
{% endblock main %}
+
56
+
57

administration/urls.py

1 addition and 0 deletions.

View changes Hide changes
1
1
from django.contrib.auth import views as auth_views
2
2
from . import views
3
3
from django.utils.translation import gettext_lazy as _
4
4
5
5
urlpatterns = ([
6
6
    path('', views.index, name='administration-index'),
7
7
    path(_('pre-registration'), views.pre_registration, name='administration-pre-registration'),  # HOLD
8
8
    path(_('settings'), views.settings, name='administration-settings'),
9
9
    path(_('curriculum'), views.curriculum, name='administration-curriculum'),  # TODO
10
10
    # Commented because they might very well be merged with curriculum
11
11
    #path(_('results'), views.results, name='administration-results'),
12
12
    #path(_('results/<slug:course>'), views.result, name='administration-results'),
13
13
    #path(_('results/<int:student_id>'), views.result, name='administration-results'),
14
14
    path(_('forms'), views.forms, name='administration-forms'),  # In Dutch: "Attesten"  # HOLD
15
15
    path(_('forms/<str:form>'), views.forms, name='administration-forms'),  # HOLD
16
16
    path(_('rooms'), views.rooms, name='administration-rooms'),  # TODO
17
17
    path(_('rooms/<str:room>'), views.room_detail, name='administration-room-detail'),  # TODO
18
18
    #path(_('rooms/reservate'), views.room_reservate, name='administration-room-reservate'),
19
19
    path(_('roster'), views.roster, name='administration-roster'),  # TODO
20
20
    re_path(_('roster/(?P<begin>[0-9]{2}-[0-9]{2}-[0-9]{4})/(?P<end>[0-9]{2}-[0-9]{2}-[0-9]{4})'), views.roster, name='administration-roster'),  # TODO
21
21
    path(_('jobs'), views.jobs, name='administration-jobs'),  # HOLD
22
22
    path(_('bulletin-board'), views.bulletin_board, name='administration-bulletin-board'),  # TODO
23
23
    path(_('user/<slug:slug_name>'), views.user, name='administration-user'),  # TODO
24
24
    path(_('roster/<slug:user_slug>.ics'), views.roster_ics, name='administration-roster-ics'),  # TODO
+
25
    path(_('roster/<slug:user_slug>.ics'), views.roster_ics, name='administration-roster-ics'),  # TODO
25
26
26
27
    path('login', views.login, name='administration-login'),  # FIXME
27
28
    ])
28
29

administration/views.py

12 additions and 0 deletions.

View changes Hide changes
1
1
from collections import OrderedDict
+
2
from collections import OrderedDict
2
3
from django.http import HttpResponseRedirect
3
4
import datetime
4
5
from django.urls import reverse # Why?
5
6
from django.utils.translation import gettext as _
6
7
from .models import *
7
8
from .forms import UserDataForm
8
9
from .new_roster import create_roster_rows
9
10
import administration
10
11
from django.contrib.auth.decorators import login_required
11
12
from django.contrib.auth import authenticate
12
13
from django.contrib.auth import login as login_auth
13
14
14
15
@login_required
15
16
def roster(request, begin=None, end=None):
16
17
    """Collects and renders the data that has to be displayed in the roster.
17
18
18
19
    The begin and end date can be specified. Only roster points in that range
19
20
    will be included in the response. If no begin and end are specified, it will
20
21
    take the current week as begin and end point. If it's
21
22
    weekend, it will take next week."""
22
23
23
24
    # TODO Handle given begin and end
24
25
    context = dict()
25
26
    #context = {'money' : update_balance(None)}
26
27
    template = "administration/roster.djhtml"
27
28
28
29
    if begin is None or end is None:
29
30
        today = datetime.date.today()
30
31
        if today.isoweekday() in {6,7}:  # Weekend
31
32
            begin = today + datetime.timedelta(days=8-today.isoweekday())
32
33
            end = today + datetime.timedelta(days=13-today.isoweekday())
33
34
        else:  # Same week
34
35
            begin = today - datetime.timedelta(days=today.weekday())
35
36
            end = today + datetime.timedelta(days=5-today.isoweekday())
36
37
    else:  # Changing regexes to date objects
37
38
        b = begin.split("-")
38
39
        e = end.split("-")
39
40
        begin = datetime.datetime(int(b[2]),int(b[1]),int(b[0]))
40
41
        end = datetime.datetime(int(e[2]),int(e[1]),int(e[0]))
41
42
42
43
    context['begin'] = begin
43
44
    context['end'] = end
44
45
45
46
    context['prev_begin'] = (begin - datetime.timedelta(days=7)).strftime("%d-%m-%Y")
46
47
    context['prev_end'] = (begin - datetime.timedelta(days=2)).strftime("%d-%m-%Y")
47
48
    context['next_begin'] = (end + datetime.timedelta(days=2)).strftime("%d-%m-%Y")
48
49
    context['next_end'] = (end + datetime.timedelta(days=7)).strftime("%d-%m-%Y")
49
50
50
51
    days = [begin]
51
52
    while (end-days[-1]).days != 0:
52
53
        # Human translation: Keep adding days until the last day in the array of
53
54
        # days is the same day as the last day the user wants to see the roster for.
54
55
        days.append(days[-1] + datetime.timedelta(days=1))
55
56
    context['days'] = days
56
57
57
58
    # Collecting events
58
59
    course_events = CourseEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end).order_by("begin_time")
59
60
    #university_events = UniversityEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
60
61
    #study_events = StudyEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
61
62
    #events = Event.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
62
63
    conflicts, table_code = create_roster_rows(course_events)
63
64
64
65
    context['time_blocks'] = table_code
65
66
    context['conflicts'] = conflicts
66
67
    #print(time_blocks)
67
68
    return render(request, template, context)
68
69
    # TODO Finish!
69
70
70
71
def roster_ics(request, user_slug):
71
72
    template = "administration/roster.ics"
72
73
    context = dict()
73
74
    context['events'] = CourseEvent.objects.all()  # FIXME: Filter to personal calendar items!
74
75
    return render(request, template, context)
75
76
76
77
def index(request):
77
78
    template = "administration/index.djhtml"
78
79
    #context = {'money': update_balance(None)}
79
80
    context = dict()
80
81
    context['links'] = [
81
82
        ("administration-settings",
82
83
         _("Personal settings"),
83
84
         _("Edit your personal information, billing address, home address, and so on.")),
84
85
        ("administration-curriculum",
85
86
         _("Curricula"),
86
87
         _("View all information related to your curricula, including exam results.<br />"
87
88
           "You can also change your current curriculum here, or request a change.")),
88
89
        ("administration-forms",
89
90
         _("Forms"),
90
91
         _("All forms for special services can be found on this page.")),
91
92
        ("administration-rooms",
92
93
         _("Rooms"),
93
94
         _("Room occupancy, free rooms, properties, ... <br />"
94
95
           "All this and much more is available on this page.")),
95
96
        ("administration-roster",
96
97
         _("Personal roster"),
97
98
         _("Everything about your roster and events at Hasselt University is available here.")),
98
99
        ("administration-bulletin-board",
99
100
         _("Bulletin board"),
100
101
         _("From time to time, UHasselt publishes announcements regarding changes, events, ..."
101
102
           "<br />All publications are neatly organized here for easy reference.")),
102
103
        ]
103
104
104
105
    return render(request, template, context)
105
106
106
107
    pass
107
108
108
109
def pre_registration(request):
109
110
    user_data_form = UserDataForm()
110
111
    template = "administration/pre_registration.djhtml"
111
112
    context = dict()
112
113
113
114
    if request.method == 'POST':
114
115
        user_data_form = UserDataForm(request.POST)
115
116
        context['user_data_form'] = user_data_form
116
117
        if user_data_form.is_valid():
117
118
            user_data_form.save()
118
119
            context['messsage'] = _("Your registration has been completed. You will receive an e-mail shortly.")
119
120
        else:
120
121
            context['messsage'] = _("The data you supplied had errors. Please review your submission.")
121
122
    else:
122
123
        context['user_data_form'] = UserDataForm(instance = user_data_form)
123
124
124
125
    return render(request, template, context)
125
126
    pass
126
127
127
128
@login_required
128
129
def settings(request):
129
130
    user_data = UserData.objects.get(user=request.user)
130
131
    user_data_form = UserDataForm(instance = user_data)
131
132
    template = "administration/settings.djhtml"
132
133
    context = dict()
133
134
    #context = {'money' : update_balance(None)}
134
135
135
136
    if request.method == 'POST':
136
137
        user_data_form = UserDataForm(request.POST, instance = user_data)
137
138
        context['user_data_form'] = user_data_form
138
139
        if user_data_form.is_valid():
139
140
            user_data_form.save()
140
141
            context['messsage'] = _("Your settings were successfully updated.")
141
142
        else:
142
143
            context['messsage'] = _("The data you supplied had errors. Please review your submission.")
143
144
    else:
144
145
        context['user_data_form'] = UserDataForm(instance = user_data)
145
146
146
147
    return render(request, template, context)
147
148
148
149
@login_required
149
150
def bulletin_board(request):
150
151
    context = dict()
151
152
    #context = {'money' : update_balance(None)}
152
153
    context['exam_commission_decisions'] = ExamCommissionDecision.objects.filter(user=request.user)
153
154
    context['education_department_messages'] = EducationDepartmentMessages.objects.all()
154
155
    for item in context['education_department_messages']:
155
156
        print(item.text)
156
157
    template = "administration/bulletin_board.djhtml"
157
158
    return render(request, template, context)
158
159
159
160
def jobs(request):
160
161
    context = dict()
161
162
    #context = {'money' : update_balance(None)}
162
163
    template = "administration/jobs.djhtml"
163
164
    #@context['decisions'] = ExamCommissionDecision.objects.filter(user=request.user)
164
165
    return render(request, template, context)
165
166
166
167
167
168
@login_required
168
169
def curriculum(request):
169
170
    context = dict()
170
171
    #context = {'money' : update_balance(None)}
171
172
    template = "administration/curriculum.djhtml"
172
173
    context['curricula'] = Curriculum.objects.filter(student=request.user)
173
174
    for item in context['curricula']:
174
175
        for co in item.course_programmes_results():
175
176
            print(co)
176
177
    return render(request, template, context)
177
178
178
179
def result(request):
179
180
    return render(request, template, context)
180
181
181
182
@login_required
182
183
def results(request):
183
184
    results = CourseResult.objects.filter(student=request.user)
184
185
    template = "administration/results.djhtml"
185
186
    # TODO
186
187
    return render(request, template, context)
187
188
188
189
def forms(request):
189
190
    context = dict()
190
191
    #context = {'money' : update_balance(None)}
191
192
    template = "administration/forms.djhtml"
192
193
    return render(request, template, context)
193
194
194
195
def user(request, slug_name):
195
196
    pass
196
197
197
198
def rooms(request):
198
199
    context = dict()
199
200
    #context = {'money' : update_balance(None)}
200
201
    context['rooms'] = Room.objects.all()
201
202
    context['room_reservations'] = RoomReservation.objects.all()
202
203
    context['course_events'] = CourseEvent.objects.all()
203
204
    context['blocks'] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
204
205
205
206
    # Collecting all rooms that are free for at least one two hours from now
206
207
    now = datetime.datetime.now(datetime.timezone.utc)
207
208
    end = now + datetime.timedelta(hours=2)
208
209
    free_rooms = dict()
209
210
    for room in context['rooms']:
210
211
        if room.reservation_possible(now, end):
211
212
            event = room.next_event(end)
212
213
            reservation = room.next_reservation(end)
213
214
            if event is None and reservation is None:
214
215
                free_rooms[room] = None
215
216
            elif reservation is not None:
216
217
                free_rooms[room] = event.begin_time
217
218
            elif event is not None:
218
219
                free_rooms[room] = reservation.begin_time
219
220
            elif event.begin_time < reservation.begin_time:
220
221
                free_rooms[room] = event.begin_time
221
222
            else:
222
223
                free_rooms[room] = reservation.begin_time
223
224
    context['free_rooms'] = free_rooms
224
225
225
226
    template = "administration/rooms.djhtml"
226
227
    return render(request, template, context)
227
228
228
229
def room_detail(request, room):
229
230
    template = "administration/room_detail.djhtml"
230
231
    context = dict()
231
232
    #context = {'money' : update_balance(None)}
232
233
    room = Room.objects.get(name=room)
233
234
    context['room'] = room
234
235
    context['reservations'] = RoomReservation.objects.filter(room=room).filter(begin_time__gte=datetime.datetime.now())
235
236
    context['course_events'] = CourseEvent.objects.filter(room=room).filter(begin_time__gte=datetime.datetime.now())
236
237
    # Building the room occupancy of today:
237
238
    today = datetime.date.today()
238
239
    if today.isoweekday() in {6,7}:  # Weekend
239
240
        today = today + datetime.timedelta(days=8-today.isoweekday())
240
241
241
242
    context['days'] = [today]
242
243
243
244
    # Collecting events
244
245
    course_events = CourseEvent.objects.filter(room=room).filter(begin_time__date=today)
245
246
    print(course_events)
246
247
    #university_events = UniversityEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
247
248
    #study_events = StudyEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
248
249
    #events = Event.objects.filter(begin_time__gte=begin).filter(end_time__lte=end)
249
250
250
251
    conflicts, table_code = create_roster_rows(course_events)
251
252
    context['time_blocks'] = table_code
252
253
    context['conflicts'] = conflicts
253
254
    print(context['time_blocks'])
254
255
    return render(request, template, context)
255
256
256
257
def login(request):
+
258
    context = dict()
+
259
    context["departures_diepenbeek"] = bus.arrivals(["401474","401475"])
+
260
    #for testing: context["departures_diepenbeek"] = bus.arrivals(["205919","205916","205915"])
+
261
    context["departures_dusart"] = bus.arrivals(["403041","403040"])
+
262
    template = 'administration/buses.djhtml'
+
263
    return render(request, template, context)
+
264
+
265
+
266
+
267
+
268
def login(request):
257
269
    context = dict()
258
270
    #context = {'money' : update_balance(None)}
259
271
    if request.method == "POST":
260
272
        name = request.POST['name']
261
273
        passphrase = request.POST['pass']
262
274
        user = authenticate(username=name, password=passphrase)
263
275
        if user is not None: # The user was successfully authenticated
264
276
            print("YA")
265
277
            login_auth(request, user)
266
278
            return HttpResponseRedirect(request.POST['next'])
267
279
        else: # User credentials were wrong
268
280
            context['next'] = request.POST['next']
269
281
            context['message'] = _("The given credentials were not correct.")
270
282
    else:
271
283
        context['next'] = request.GET.get('next', None)
272
284
        if context['next'] is None:
273
285
            context['next'] = reverse('administration-index')
274
286
275
287
    template = 'administration/login.djhtml'
276
288
277
289
    return render(request, template, context)
278
290

docs/TODO.org

6 additions and 5 deletions.

View changes Hide changes
1
1
This repository is my work for my bachelor's assignment for the study of
2
2
Informatics at [[https://uhasselt.be/][Hasselt University]]. Because of the sheer size of the project,
3
3
it's imperative that I keep track of all the things that have to be done.
4
4
5
5
In this file, I try to collect them all, in a structurally sound way.
6
6
It's possible that this file will be removed in the future, to be combined with
7
7
another file to make use of Org's clocking features, but for now, everything
8
8
will be listed here.
9
9
10
10
* Agora
11
11
*Note: Agora is NOT a priority right now!* This has been discussed with the
12
12
 promotor, and implementing the administration and courses system is a LOT more
13
13
 important than having a social platform. Nevertheless, once Courses and
14
14
 Administration are finished, work on Agora can commence, thus if there is work
15
15
 that should be done, it will be listed here, to avoid forgetting it.
16
16
** Models
17
17
** Views
18
18
** Templates
19
19
** Forms
20
20
*** TODO Post form
21
21
*** TODO Group form
22
22
*** TODO Account settings form
23
23
*** TODO Account collection form
24
24
** Urls
25
25
26
26
* Courses
27
27
** Models
28
28
*** TODO Implement group of student in a course
29
29
Dixit Lamotte: "Some studies are so big, the students have to be split up in
30
30
different groups." Thus, implement a system where the students /can/ be split in
31
31
groups by the education team of the course. If no groups exist, then they're all
32
32
treated as one giant group.
33
33
** Views
34
34
** Templates
35
35
** Forms
36
36
** Urls
37
37
** Other
38
38
39
39
* Administration
40
40
** PAGES
41
41
Eventually, a finished page consists of
42
42
- A finished template
43
43
- All models that can be accessed from that page, are finished
44
44
- A working view function
45
45
- A working URL link
46
46
- If applicable, working forms (= All forms can initiate, store, and modify
47
47
  data, and display the right error messages)
48
48
This does not include CSS or other things that overlap multiple pages. This
49
49
checklist therefore is a list of all pages that are basically done, and don't
50
50
need further action.
51
51
- [ ] Roster
52
52
- [X] Bulletin Board
53
53
- [ ] Index
54
54
- [ ] Curriculum
55
55
- [ ] Pre-registration
56
56
- [ ] Settings
57
57
- [ ] Forms
58
58
- [ ] Jobs
59
59
- [ ] Rooms
60
60
- [ ] Login
61
61
*** Rooms
62
62
**** TODO SVG rooms in an HTML canvas
63
63
That would make them clickable, so information about the rooms at UHasselt can
64
64
be retrieved by just clicking on them. You'd have to make an SVG blueprint of
65
65
the campus but eh.
66
66
** Notes
67
67
At this moment: *Implement what is already in the models.* By finishing what I
68
68
already have, I can create space in my mind for the new things.
69
69
** Models
70
70
*** TODO IBAN validator
71
71
IBAN numbers have a special format, which needs to be valid. For this, a
72
72
validator must be written.
73
73
*** TODO BIC validator
74
74
See [[IBAN validator]]
75
75
*** *ALERT* SQL standard issues!
76
76
I've got several fields that should be unique, but can also be null.
77
77
SQLite indicates two null values in the same column as a NOT UNIQUE,
78
78
but that's wrong, according to the SQL standard. This excerpt from the
79
79
PostgreSQL documentation:
80
80
In general, a unique constraint is violated if there is more than one row
81
81
 in the table where the values of all of the columns included in the constraint
82
82
are equal.
83
83
 However, two null values are never considered equal in this comparison.
84
84
 That means even in the presence of a unique constraint it is possible to
85
85
 store duplicate rows that contain a null value in at least one of the
86
86
constrained columns.
87
87
 This behavior conforms to the SQL standard,
88
88
 but we have heard that other SQL databases might not follow this rule.
89
89
 So be careful when developing applications that are intended to be portable.
90
90
** Views
91
91
*** TODO Forms, documents, ... generators
92
92
This is mainly about the legal documents that should be generated for students,
93
93
like degrees, evidence of being a student, ... These are often not to display
94
94
information, but should be put out as a PDF file, that the user can then print.
95
95
This should be done using the ReportLab Python PDF library.
96
96
Check out [[file:///home/simba/Documentation/Django/howto/outputting-pdf.html]] for
97
97
more information on how to do this.
98
98
** Templates
99
99
** TODO Roster
100
100
** TODO Personal settings
101
101
** TODO Public page
102
102
** Forms
103
103
*** TODO Personal details form
104
104
** Urls
105
105
** Other
106
106
*** TODO Implement roster system
107
107
All students (and staff) have personal rosters. This system should be able to
108
108
automatically update that. The roster will automatically show the following:
109
109
- Course schedules :: For all courses that the student follows, show the
110
110
     scheduled rooms /for their group/. If no groups are made, show the complete
111
111
     course schedule.
112
112
- Exam roster :: Show all exams of the student.
113
113
- Room reservations :: If a student has reserved a room, that will show up in
114
114
     their roster.
115
115
- Custom schedulings :: The user can also make custom schedulings, and attach
116
116
     necessary info to them.
117
117
118
118
The roster automatically opens on the current week, except when it's Saturday or
119
119
Sunday; then it shows next week.
120
120
All this data is presented through a clear and nice HTML page, and is
121
121
automatically updated in a personal iCal-file, that the user can connect to.
122
122
123
123
If that is finished, make a special form to ask for generic planning from a
124
124
certain study, course, ...
125
125
*** TODO Implement alumni system
126
126
UHasselt Alumni need to be able to give a new e-mail address. This should become
127
127
available when one has obtained a degree.
128
128
*** TODO Implement study costs system
129
129
The costs that have to be paid, must be recorded, and be presented. Data from
130
130
each year needs to be available. Check for what should be recorded at [[https://uhintra02.uhasselt.be/studdosst/sdsInschrijvingsgeld.aspx][the website]].
131
131
*** TODO System for rulings exam committee
132
132
These are probably messages that are sent out to a specific user, regarding
133
133
special measures, or some stuff like that.
134
134
*** TODO System for automatic creation of exam schedules
135
135
This system checks all current students, and needs the following info:
136
136
- For each Course:
137
137
  - The (amount of) students
138
138
  - The type of exam (verbal, writing, ...)
139
139
  - (Optionally) a notification
140
140
  - The amount of exams that have to take place
141
141
142
142
And attempts to fulfill the following requirements:
143
143
- *All exams for model trajects are spread as far as possible from one another*
144
144
- No student has overlapping exams
145
145
- All exams must take place in the given timespan
146
146
- Different exams can be given in the same room, but the maximal capicity
147
147
  must be respected
148
148
- The algorithm prefers interspacing of 2 empty seats per student. These empty
149
149
  seats may be occupied by students from other exams.
150
150
- Exams take place only in rooms with at least *double* the amount of students
151
151
  for that exam (to allow spacing). Of course, these spaces can be occupied by
152
152
  another exam batch.
153
153
- Exams that require special equipment (e.g. computers, ...) must be respected
154
154
- Rooms that already have reservations will be overridden, but a warning will be
155
155
  placed to inform about the deletion of the previous reservation.
156
156
157
157
The data is then printed to the screen, after which it can be verified. If
158
158
everything is okay, the user can accept the proposed planning, after which the
159
159
room reservations are automatically carried out.
160
160
After this point, students can view their exam rosters, and their personal
161
161
schedules are automatically updated.
162
162
163
163
*** TODO Refactoring of roster functionality
164
164
The roster needs a lot of preparation before being sent to the template. It's
165
165
currently hastly written and in the view module, but it can't stay there.
166
166
In the future, make a special roster module, and move all functionality there.
167
167
Refactor the functions, make tests so they're safe against errors, and so on.
168
168
* Report
169
169
All this needs to be put together in a giant report. For comparison: Joris'
170
170
thesis was a whopping 84 pages. Given the size of my project, I think I won't be
171
171
much below that.
172
172
** Points to talk about
173
173
*** TODO Why this MUST NOT be the final version
174
-
Joeni should not be the end, because a website is not the right medium for the
+
174
    CLOSED: [2018-08-14 Tue 23:17]
+
175
Joeni should not be the end, because a website is not the right medium for the
175
176
main digital platform of a university. Explain how the current UI is an example
176
177
of what could be. Also mention that the current existing database is suited for
177
178
directly hooking into with the new program.
178
179
*** TODO Why JavaScript is actively banned
179
-
    Explain the client side problem, the advantages of server-only programming,
+
180
    CLOSED: [2018-08-14 Tue 23:17]
+
181
    Explain the client side problem, the advantages of server-only programming,
180
182
    and my law: "If you can't make your website function properly without
181
183
    JavaScript, it shouldn't be a website in the first place."
182
184
*** TODO Explain lightweight HTML5/CSS3 usage
183
-
    Explain the benefits of providing _meaning_ through good use of HTML5, and
+
185
    CLOSED: [2018-08-14 Tue 23:17]
+
186
    Explain the benefits of providing _meaning_ through good use of HTML5, and
184
187
    why CSS3 is made using SCSS.
185
188
    Also give some examples of what the low use of divs and classes brings for
186
189
    advantages, including for impaired web users
187
190
*** TODO Django/Python
188
191
    Defend the usage of Django and Python. Explain also why other languages
189
192
    may've been beneficial, but Django was the most compelling reason for
190
193
    Python, and why Python isn't a bad choice after all, despite the better idea
191
194
    of Haskell/Clojure/...
192
195
    Also: Why no standalone software: Because that can be done later, but web
193
196
    based is what it is now, and that needs replacement. Native software can be
194
197
    done later if necessary.
195
198
*** TODO PingPing/EveryonePrint
196
-
    Explain how this was achieved.
197
-
*** TODO Caching
198
199
*** TODO Security
199
200
    Basically explain how Django has built-in security, for what exploits etc.
200
201
*** TODO Org
201
202
    Tricky one. Explain why Orgmode-syntax is allowed, how this is implemented
202
203
    (DTL filter), how to disable, and why this shouldn't pose a security threat.
203
204
*** TODO Why standards are followed, even if that breaks with certain browsers
204
205
*** TODO Why user data is stored in a different table and connected 1->1 with User
205
206
Because this is what is recommended in the Django documentation, and it makes it
206
207
way easier to add new fields, or remove some, in the future.
207
208
https://docs.djangoproject.com/en/2.0/topics/auth/customizing/#specifying-a-custom-user-model
208
209
*** TODO Write about how some functionality is now implemented by implication
209
210
An example: There's now no dedicated button to download a scorecard from the
210
211
curriculum.
211
212
However, because the pages are so simple and clear, browsers like Firefox allow
212
213
that same functionality with their builtin "print webpage" capability. An
213
214
example of 90% of the functionality implemented with 10% of the effort.

docs/thesis/beveiliging.org

5 additions and 5 deletions.

View changes Hide changes
1
1
Web-applicaties worden blootgesteld aan tal van mogelijke beveiligingsproblemen.
2
2
Een beetje /cracker/ kan een onbeveiligde website in weinig tijd
3
3
binnendringen.\\
4
4
Mede dankzij het gebruik van Django zijn de meeste mogelijke veiligheidslekken
5
5
gedicht. De belangrijkste onderwerpen (en gemaakte afwegingen) worden hier uitgelegd.
6
6
** Cross site scripting
7
7
Cross site scripting (XSS) laat toe om scripts te injecteren in de browsers van andere
8
8
gebruikers door bv. scripts op te slaan in de databank, die dan later worden
9
9
uitgelezen en op de computer van andere gebruikers wordt uitgevoerd.
10
10
11
11
Binnen Django wordt XSS opgelost door middel van
12
12
/[[https://docs.djangoproject.com/en/2.0/ref/templates/language/#automatic-html-escaping][automatic HTML escaping]]/; de data die gebruikers ingeven, wordt behandeld als "onveilig".
13
13
*** Orgmode
14
14
Binnen Joeni kan gebruik worden gemaakt van Orgmode-syntax om teksten van 
15
15
opmaak te voorzien, zoals vette tekst, hyperlinks, lijsten enz.
16
16
17
17
Het is technisch gezien ook mogelijk om broncode in Org te markeren, zelfs om
18
18
deze uit te laten voeren, met alle [[https://orgmode.org/org.html#Code-evaluation-security][veiligheidsrisico's]] die daaruit volgen.
19
19
20
20
Ik heb toch geopteerd om Orgmode-syntax toe te laten voor data die door
21
21
gebruikers wordt verstuurd, maar *enkel* voor personeel van de UHasselt.
22
22
Personeelsleden kunnen makkelijker aansprakelijk gehouden worden voor misbruik
23
23
van de hen aangeleverde voorrechten, en de mogelijke gevolgen van dergelijk misbruik
24
24
zullen volgens mij afdoende werken om XSS via Orgmode tegen te gaan. Moest dat
25
25
niet kloppen, dan kan Orgmode altijd gemakkelijk uitgeschakeld worden, slechts
26
26
met een tolereerbaar verlies aan opmaak binnen Joeni.
27
27
28
28
** Externe malafide programmatuur
29
29
Bij het opvragen van scripts buiten de eigen server is er steeds een risico dat
30
30
er malafide code wordt binnengehaald; men weet niet welke acties ondernomen
31
31
worden op die andere servers om kraken tegen te gaan.\\
32
32
Dit is al verscheidene keren voorgevallen , en de kern van het probleem is tot nu
33
-
toe nog altijd niet opgelost, omdat het niet kán worden opgelost: Downloaden van
+
33
toe nog altijd niet opgelost, omdat het niet kán worden opgelost: Downloaden van
34
34
ongecontroleerde scripts houdt een inherent veiligheidsrisico in.
35
35
36
36
Joeni lost dit op door simpelweg _geen_ externe scripts in te laden. Dit is
37
37
namelijk ook een reden waarom /client-side scripting/ overal vermeden wordt;
38
38
het opent een deur tot problemen waarover weinig controle mogelijk is.
39
39
40
40
Alle software, media, /stylesheets/, bibliotheken, ... worden vanaf de server
41
41
gedraaid. 
42
42
** Clickjacking
43
-
+
43
44
44
** Cross site request forgery
45
-
Cross site request forgery (CSRF) 
+
45
Cross site request forgery (CSRF) 
46
46
47
47
** Kraken van wachtwoorden en -zinnen
48
-
*** Geen verplichte wijzigingen
49
-
+
48
*** COMMENT Geen verplichte wijzigingen
+
49

docs/thesis/blackboard.org

7 additions and 7 deletions.

View changes Hide changes
1
1
Blackboard, het digitale platform dat wordt aangeleverd door Blackboard Inc.,,
2
2
wordt (voornamelijk) op de UHasselt gebruikt voor het verspreiden van
3
3
lesmateriaal onder de studenten en het maken van aankondigingen betreffende het
4
4
vak of opdrachten die moeten worden ingediend.
5
5
6
6
Een groot deel van hoe Joeni gebouwd is, bestaat uit functionaliteit die
7
7
Blackboard aanbiedt, en dat is niet zonder reden. Blackboard is een slechte zaak
8
8
voor de universiteit en haar studenten, en daar zijn verschillende redenen voor.
9
9
10
10
*** Onbetrouwbaarheid
11
11
Veel Amerikaanse universiteiten hebben /vroeger/ al samengewerkt met Blackboard,
12
12
met de nadruk op vroeger. Er zijn op het internet tal van artikelen te vinden
13
13
over deze universiteiten die klagen over het stelselmatig uitvallen van
14
14
Blackboard@@latex:\cite{bb-blackout1}\cite{bb-blackout2}@@, verlies van
15
15
data@@latex:\cite{bb-dataloss}@@ en
16
16
crashes@@latex:\cite{bb-crash}@@,
17
17
Er zijn ook hier en daar pagina's opgericht door studenten die een iets
18
18
ongenuanceerdere toon aanslaan zoals een [[https://web.archive.org/web/20110719215525/http://wwwapps.ivytech.edu/phpbb/viewtopic.php?p=14937&highlight=&sid=461341d24f37a90f0f83c16fc3bedcae]["Ik haat Blackboard"-groep]], maar hierop
19
19
zal niet verder worden ingegaan.
20
20
21
21
Uit persoonlijke ervaringen weet ik zelf ook dat Blackboard soms niet
22
22
werkt naar behoren. Een voorbeeld hiervan was een opdracht voor het vak Computernetwerken,
23
23
waarin Blackboard de inzendingen weigerde omdat deze "gevaarlijk" waren, ook al
24
24
waren dit gewoon tekstbestanden met een .py-extensie. Het bestand in een
25
25
zip-bestand plaatsen werkte wel.\\
26
26
Zo nu en dan was de website op zich gewoon niet bereikbaar, en gaf het een HTTP
27
27
503-error. Na een tijdje waren deze problemen wel weg.
28
28
29
29
Enige nuance vereist ook dat deze universiteiten vaak ook veel meer van hun
30
30
digitale behoeften op de schouders van Blackboard plaatsen, en het dus ook
31
31
waarschijnlijker is dat ze in contact komen met problemen. Maar de frequentie
32
32
van deze problematiek doet vermoeden dat het zeker geen eenmalige problemen zijn.
33
33
*** Hoge kosten
34
34
Tijdens een vergadering van de Studentenraad kwam naar voren dat het contract
35
35
met Blackboard inc. de UHasselt *jaarlijks meer dan €100.000* kost. Dit is geld
36
36
dat makkelijk gespendeerd kan worden aan andere zaken als voor een andere
37
37
oplossing gekozen wordt.
38
38
39
39
Als tegenargument kan natuurlijk worden aangevoerd dat dit gewoon de prijs is
40
40
die men betaalt voor dergelijke software, en dat informatici aannemen voor
41
41
interne software te schrijven minstens zo duur is. Het is echter de vraag of die
42
42
prijs opweegt tegen de punten die in dit hoofdstuk worden aangehaald.
43
43
*** Gebruiksvoorwaarden 
44
44
De gebruiksvoorwaarden die Blackboard oplegt aan hun gebruikers staat geenszins
45
45
in verhouding tot wat nodig is om de goede werking van de dienst te waarborgen.
46
46
Deze voorwaarden gaan in enkele gevallen uiterst ver, gegeven enkele voorbeelden hiervan.
47
47
48
48
Het feit dat deze eisen gesteld worden is een direct gevolg van de  [[Onvrije software][propriëtaire
49
49
software]] die Blackboard is: Onvrije software geeft de ontwikkelaar ervan
50
50
oneerlijke macht over de gebruikers, en Blackboard inc. heeft die macht
51
51
uitgeoefend.
52
52
**** Schending van de privacy
53
53
De studenten hebben een recht op privacy bij het uitvoeren van hun academische
54
54
verantwoordelijkheden, en dus ook bij het gebruik van de benodigde software hiervoor.
55
55
56
56
Blackboard heeft echter bedenkingen hiermee, en vereist dat hun gebruikers (en
57
57
dus ook de studenten van de UHasselt) akkoord gaan met hun privacyverklaring.@@latex:\cite{bb-privacy}@@
58
58
Hierin staan dan teksten te lezen zoals het volgende:
59
59
#+BEGIN_QUOTE
60
60
*Analytics and marketing.* We analyze usage information for sales and 
61
61
marketing purposes and for trends about our visitors and their demographics and
62
62
how they use our websites. This analysis is necessary to further our legitimate
63
63
 interest in understanding our users and how they interact with us and our
64
64
websites, improving our websites and communication 
65
65
with you (including for marketing purposes).
66
66
#+END_QUOTE
67
67
Het komt erop neer dat informatie die ze inzamelen gebruikt zal worden voor
68
68
reclamedoeleinden.
69
69
70
70
Het probleem hiermee is dat studenten gewoon geen keuze hebben of ze hiermee
71
71
akkoord gaan of niet: Door niet akkoord te gaan krijgen ze geen toegang tot het
72
72
studiemateriaal van hun docenten, zijn ze niet op de hoogte van taken, ... Dit
73
73
is natuurlijk ook een gevolg van het gebruik van [[Onvrije software][onvrije software]], maar dat praat het
74
74
geenzins goed.
75
75
76
76
De UHasselt heeft een verplichting aan haar studenten om hun rechten te
77
77
beschermen als ze willen studeren, en Blackboard maakt hier misbruik van hun
78
78
positie om data van studenten te misbruiken, of ze dat nu willen of niet.
79
79
Het enige wat we hebben is een "belofte" dat de privacy serieus genomen wordt,
80
80
maar met dergelijke tegenstrijdige verklaringen is het maar de vraag hoe
81
81
betrouwbaar dat is.
82
82
83
83
Tot slot is het verwerken van deze gegevens mogelijk in strijd met de Algemene
84
84
Verordering Gegevensbescherming; het verwerken van deze gegevens voor
85
85
marketingdoeleinden mag enkel met
86
86
expliciete toestemming van de gebruiker.@@latex:\cite{eu-gdpr}@@ 
87
87
Maar opnieuw: de gebruiker heeft hier
88
88
als student (of docent) niet echt een keus of hij/zij akkoord gaat of niet. Het is maar
89
89
de vraag wat een toestemming die op dergelijke manier verkregen wordt nu
90
90
eigenlijk waard is.
91
91
92
92
**** Kopieerrechten
93
93
Auteurs van creatieve werken zouden zelf moeten kunnen bepalen wanneer hun werken
94
94
(publiek domein niet meegerekend) gebruikt mogen worden voor commerciële
95
95
doeleinden. Blackboard stelt echter in hun gebruiksvoorwaarden:@@latex:\cite{bb-tos}@@
96
96
#+BEGIN_QUOTE
97
97
By submitting, posting or displaying Content on or through the Products,
98
98
 you grant us a worldwide, non-exclusive, royalty-free license (with the right to sublicense)
99
99
 to use, host, store, copy, reproduce, process, adapt, modify, publish, transmit,
100
100
create derivative works from, communicate, display, and/or distribute such Content
101
101
 in any and all media or distribution methods (now known or later developed) as
102
102
part of providing any of the Products. You agree that this license includes the
103
103
right for Blackboard to provide, promote, and improve the Products and to make
104
104
Content submitted to or through the Products available to other institutions or
105
105
individuals as part of providing the Products (including after termination of
106
106
your use of the Products) and in accordance with your privacy settings. You
107
107
represent and warrant that you have all the rights, power and authority
108
108
necessary to grant the rights granted herein to any Content that you submit.
109
109
110
110
../..
111
111
112
112
Blackboard may exercise the rights to your Content granted under these Terms
113
113
without liability for payment of any guild fees, residuals, payments, fees, or
114
114
royalties payable under any collective bargaining agreement, licensing
115
115
arrangement or otherwise. 
116
116
#+END_QUOTE
117
117
Er is geen reden voor Blackboard om te eisen van studenten (en andere gebruikers
118
118
zoals docenten) dat Blackboard inc. hun werken voor praktisch alles mag
119
119
 gebruiken, zonder enige vorm van compensatie of naamsvermelding. Opnieuw maken ze hiermee
120
120
misbruik van hun positie als digitaal platform van universiteiten om eisen te
121
121
stellen aan gebruikers waar ze normaal vrijwel nooit mee akkoord zouden gaan.
122
122
123
123
*** Onvrije software
124
124
De software die Blackboard gebruikt, is propriëtaire software, waarvan de
125
125
werking niet bekend is, in die zin dat de UHasselt geen inzage heeft in hoe hun
126
126
data wordt afgehandeld. Gegeven [[Gebruiksvoorwaarden][de gebruiksvoorwaarden]] doet dit vermoeden dat er
127
127
ook activiteiten gebeuren die niet noodzakelijk zijn, zoals het gebruik van de
128
128
data voor marketing en profilering van studenten.
129
129
130
130
De propriëtaire software maakt dit mogelijk; door de broncode verborgen te
131
131
houden en fundamentele rechten te ontzeggen,
132
132
kan er geen controle plaatsvinden op wat er nu echt gebeurt met de data
133
133
van onze studenten. Sterker: Het gebrek aan controle (en de positie die
134
134
Blackboard heeft binnen de universiteit), samen met de wetenschap dat de
135
135
gebruikers hier weinig verweer tegen kunnen bieden, zet aan tot misbruik van die
136
136
machtspositie, en het implementeren van functionaliteit die de gebruikers nefast
137
137
behandeld. Dit wordt ook wel /malware/ genoemd.
138
138
139
139
We kunnen zelf ook de software niet aanpassen naar de behoeften van de UHasselt,
140
140
ook hiervoor zijn we afhankelijk van Blackboard inc.
141
141
142
142
Kortom: Doordat Blackboard geen vrije software is, heeft de universiteit geen
143
143
controle over de software.
144
144
145
145
Joeni zou voor de student op dezelfde manier als Blackboard bereikt worden, maar
146
146
de broncode van Joeni is wél vrij in te zien (dit is namelijk ook één van de
147
147
veiligheidsgaranties). De studenten kunnen er sowieso redelijkerwijs op vertrouwen dat de
148
148
universiteit hun rechten ter harte neemt, maar met vrije software hebben ze ook
149
149
een garantie hiervoor.
150
150
*** Toledo & Minerva/Ufora
151
151
De Universiteit Gent[fn:minerva], Vrije Universiteit Brussel en Katholieke Universiteit Leuven maken geen gebruik van
152
152
externe bedrijven voor hun digitale behoeften. In plaats daarvan gebruiken zij
153
153
software "van het huis"; de software is ontwikkeld voor en door de universiteit
154
154
zelf. Het toont aan dat een universitair digitaal platform bouwen mogelijk is,
155
155
en dat het academische standaarden kan aanhouden. Er is geen nood om te
156
156
vertrouwen op een bedrijf zoals Blackboard, en genoegen te nemen met een
157
157
"algemene" oplossing.
158
158
159
159
[fn:minerva] In het afgelopen academiejaar heeft de UGent een
160
-
aanbesteding uitgegeven voor bedrijven om een nieuwe Minerva te bouwen. Dit
161
-
nieuwe programma zal Ufora heten, en (het ondertussen vijftien jaar oude)
162
-
Minerva gaandeweg vervangen.@@latex:\cite{ufora}@@ Alhoewel
163
-
zij dus ook overschakelen op een extern bedrijf, kiezen zij hiermee nog steeds
164
-
voor een "persoonlijke" oplossing, en niet voor iets wat niet specifiek voor hen gemaakt is.
165
-
166
-
Natuurlijk zijn deze universiteiten aanzienlijk groter dan de UHasselt wat
167
160
betreft het aantal studenten. De Universiteit Antwerpen
168
161
gebruikt ook Blackboard als digitaal platform, en telt zelf ook al 20.000 studenten.
169
162
Maar de UHasselt heeft eerder zelf ook al de
170
163
ambitie geuit om te blijven groeien@@latex:\cite{uhasselt-groeit}@@, en voor een
171
164
langetermijnoplossing is een oplossing op maat zeker geen overbodige luxe.
172
165
*** Informatica binnen de UHasselt
173
166
Binnen de faculteit Wetenschappen op de UHasselt zijn er niet veel
174
167
masteropleidingen. Maar buiten de Master of Statistics wordt er wel fel ingezet
175
168
op de Master in de Informatica, met maar lieft zes (!) mogelijke
176
169
specialisatieprofielen@@latex:\cite{opleiding-informatica}@@,
177
170
wat voor een universiteit van dergelijke grootte best opvallend te noemen is.\\
178
171
Het zou een mooie troef zijn voor de (master)opleiding als de UHasselt kan tonen
179
172
dat ze genoeg vertrouwen hebben in hun eigen kunnen, en deze kennis ook inzetten
180
173
voor het onderhoud van hun eigen informatica. Vertrouwen op een hoop externe
181
174
bedrijven voor de interne IT doet dat vertrouwen niet uitstralen.
182
175
183
176
Dit is evenwel niet zozeer een punt tégen Blackboard, maar wel een punt om te
184
177
ijveren om met het ALIPA-project nu ook in te zetten op een goede oplossing van
185
178
eigen makelij.
186
179
*** Reden(en) tot stopzetting
187
180
In de studentenraad is ter ore gekomen dat de integratie met Blackboard, ondanks
188
181
bovenstaande punten, verder wordt gezet middels een app die zou integreren met Blackboard.
189
182
190
183
Misschien is het beter om de samenwerking echter stop te zetten. Voor ALIPA zou
191
184
het makkelijker zijn om de vernieuwing door te laten gaan als er controle is
192
185
over zo'n cruciaal onderdeel van de universiteit.
193
186
194
187
Met Joeni is er een voorstel dat laat zien hoe de functies die nu door
195
188
Blackboard worden aangevoerd, geïntegreerd kunnen worden in een centrale
196
189
oplossing voor de studenten. Het is niet zo moeilijk als op het eerste zicht zou
197
190
lijken, en veegt direct alle gegeven problemen van de baan.
198
191
+
192
[fn:minerva] In het afgelopen academiejaar heeft de UGent een
+
193
aanbesteding uitgegeven voor bedrijven om een nieuwe Minerva te bouwen. Dit
+
194
nieuwe programma zal Ufora heten, en (het ondertussen vijftien jaar oude)
+
195
Minerva gaandeweg vervangen.@@latex:\cite{ufora}@@ Alhoewel
+
196
zij dus ook overschakelen op een extern bedrijf, kiezen zij hiermee nog steeds
+
197
voor een "persoonlijke" oplossing, en niet voor iets wat niet specifiek voor hen gemaakt is.
+
198
voor een "persoonlijke" oplossing, en niet voor iets wat niet specifiek voor hen gemaakt is.

docs/thesis/dankwoord.org

16 additions and 12 deletions.

View changes Hide changes
1
1
indirect hulp hebben verschaft aan het mogelijk maken van dit werk. Ik vind het
2
2
bijzonder belangrijk om deze mensen hiervoor te bedanken, en ze te vermelden in
3
3
het werk waar ze allemaal ook deel van uitmaken.
4
4
5
5
- Jonathan Driessen :: Mijn levenspartner en inspiratie voor de naam van dit
+
6
     aan de problemen van de software bij het personeel.
+
7
- Hilde Cleeren :: Net als Ines werkzaam voor de lokaalreservaties. Zij had ook
+
8
                   al problemen aangekaart omtrent de software, en heeft mij
+
9
                   voorzien van een zelfgemaakte presentatie over dat probleem.
+
10
- Ines Boonen :: Contactpersoon voor de lokaalreservaties, die mij heeft
+
11
                 geholpen met een beeld te krijgen van hoe lokalen op de
+
12
                 universiteit ingepland worden.
+
13
- Jonathan Driessen :: Mijn levenspartner en inspiratie voor de naam van dit
6
14
     project. Hij heeft Joeni ook getest en waardevolle feedback voorzien voor
7
15
     de layout van het uurrooster.
8
16
- prof. dr. Wim Lamotte :: Mijn promotor. Deze bachelorproef was een
+
17
                   dit verbeterd kon worden. Alsook een opmerking dat er
+
18
                   verschillen zijn voor de layout van knoppen bij formulieren
+
19
- prof. dr. Wim Lamotte :: Mijn promotor. Deze bachelorproef was een
9
20
     persoonlijk gekozen onderwerp, en hij heeft hierop snel geantwoord met een
10
21
     betuiging van interesse. Ook heeft hij me op weg geholpen met het in
11
22
     contact brengen van personen die informatie konden verschaffen tijdens het
12
23
     onderzoek.
13
24
- ir. Bruno Janssen ::
14
-
- Ines Boonen :: Contactpersoon voor de lokaalreservaties, die mij heeft
15
-
                 geholpen met een beeld te krijgen van hoe lokalen op de
16
-
                 universiteit ingepland worden.
17
-
- 
18
-
- Hilde Cleeren :: Net als Ines werkzaam voor de lokaalreservaties. Zij had ook
19
-
                   al problemen aangekaart omtrent de software, en heeft mij
20
-
                   voorzien van een zelfgemaakte presentatie over dat probleem.
21
-
- Joris Herbots BSc :: Heeft Joeni getest en ...
22
-
- Mannu Lambrichts BSc :: Heeft Joeni getest ...
23
-
- Jorrit Gerets :: Heeft Joeni getest ...
24
-
- Niels Vangeneugden :: Joeni getest ...
25
-
+
25
                    planning van verschillende studierichtingen worden ingewerkt.
+
26
# - Joris Herbots BSc :: Heeft Joeni getest en ...
+
27
# - Mannu Lambrichts BSc :: Heeft Joeni getest ...
+
28
# - Niels Vangeneugden :: Joeni getest ...
+
29
26
30
Een speciaal dankwoord gaat ook uit naar de auteurs van de gebruikte software
27
31
(@@latex:\LaTeX@@, Django/Python, het GNU-project, ...). Net zoals in de fysica
28
32
bouwen we in de informatica verder
29
33
/on the shoulders of giants/[fn::Referentie naar een gelijknamig boek van Stephen Hawking].
30
34
Het belang van het vrij delen van software, algoritmes en ideeën is van
31
35
onschatbare waarde voor de (technologische) vooruitgang van de mensheid.

docs/thesis/databank.joeni.org

48 additions and 0 deletions.

View changes Hide changes
+
1
Joeni haalt alle data uit een databank op de achtergrond. Hoe de tabellen zijn
+
2
ingericht wordt in dit hoofdstuk besproken, alsook informatie gerelateerd aan de
+
3
databank.
+
4
+
5
De databank is opgedeeld in drie onderdelen, waarvan twee relevant zijn voor
+
6
deze thesis:
+
7
- Agora :: Bevat alle tabellen gerelateerd aan het communicatieplatform van
+
8
           Joeni. Agora is niet uitgewerkt en zal dus niet verder besproken
+
9
           worden.
+
10
- Administration/Beheer :: Tabellen gerelateerd aan de administratieve data van
+
11
     de studenten en de universiteit, zoals de curricula, data van de studenten
+
12
     zoals naam, adres, ...
+
13
- Courses :: Alle informatie die relevant is voor de verschillende vakken. Dit
+
14
             omvat bv. aankondigingen, links naar studiemateriaal, opdrachten, ...
+
15
*** Databank-agnostisch
+
16
Tijdens de ontwikkeling van Joeni is er altijd gebruik gemaakt van een
+
17
SQLite-databank. De reden hiervoor is omdat een databank bestaand uit een enkel
+
18
bestand zeer gemakkelijk is om mee te ontwikkelen; er moet geen aparte databank
+
19
worden geïnstalleerd, het kan op elke computer werken, en kan ook makkelijk
+
20
overgezet worden naar andere systemen, zonder risico te lopen dat er iets
+
21
foutloopt.
+
22
+
23
Toch is SQLite absoluut geen vereiste voor Joeni om te werken; door de
+
24
[[https://en.wikipedia.org/wiki/Object-relational_mapping][object-relational mapper]] kan er een heel scala aan verschillende databanken
+
25
gebruikt worden, waaronder
+
26
- MySQL (zowel [[https://dev.mysql.com/doc/refman/en/myisam-storage-engine.html][MyISAM]] als [[https://dev.mysql.com/doc/refman/en/innodb-storage-engine.html][InnoDB]], via [[https://pypi.python.org/pypi/mysqlclient][mysqlclient]])
+
27
- PostgreSQL (via [[http://initd.org/psycopg/][psycopg]])
+
28
- Oracle Database Server (via [[https://oracle.github.io/python-cx_Oracle/][cx_Oracle]])
+
29
+
30
Ermee rekening houdend dat de werking met de ORM kan variëren, is er ook nog
+
31
ondersteuning voor de volgende databanken:
+
32
- SAP SQL Anywhere (via [[https://github.com/sqlanywhere/sqlany-django][sqlany-django]])
+
33
- IBM DB2 (via [[https://pypi.python.org/pypi/ibm_db/][ibm_db]])
+
34
- Microsoft SQL Server (via [[https://django-mssql.readthedocs.io/en/latest/][django-mssql]])
+
35
- Firebird (via [[https://github.com/maxirobaina/django-firebird][django-firebird]])
+
36
- OBDC (via [[https://github.com/lionheart/django-pyodbc/][django-pyodbc]])
+
37
+
38
De UHasselt gebruikt zelf een DB2-databank om data op te slaan. Een snelle
+
39
integratie met Joeni is dus mogelijk, zonder dat daarvoor het hele
+
40
databasesysteem moet vervangen worden.
+
41
+
42
*** Administration
+
43
Tevens het grootste onderdeel van Joeni. 
+
44
+
45
*** Courses
+
46
Zoals eerder vermeld bevat Courses alle tabellen die gerelateerd zijn aan de
+
47
vakken die gevolgd kunnen worden aan de UHasselt.
+
48
vakken die gevolgd kunnen worden aan de UHasselt.

docs/thesis/huisstijl.org

73 additions and 73 deletions.

View changes Hide changes
1
-
Een mooi uitgewerkte huisstijl is essentieel voor het creëren van een gevoel van
2
-
samenhorigheid met verschillende entiteiten: Ze dienen ter onderscheiding van de
3
-
rest, en 
4
-
In Joeni wordt de huisstijl van de UHasselt verder uitgewerkt en gebruikt. In
5
-
dit hoofdstuk wordt dit in detail uitgelegd, zodat het als basis kan dienen voor
6
-
andere software.
7
-
8
-
Ik vermoed dat een deel van de huisstijl simpelweg niet met de studenten mede
9
-
gedeeld wordt; op de website wordt doorgaans gelinkt naar een "Huisstijl voor
10
-
studenten", wat doet vermoeden dat er ook een "Huisstijl voor personeel" moet
11
-
zijn, of iets in die aard.
12
-
13
-
** Logo
14
-
Joeni heeft tot doel als vervanging te dienen voor het Studentendossier en
15
-
BlackBoard. In combinatie met de relatie tot de UHasselt, wordt voor Joeni het
16
-
volgende logo gebruikt:
17
-
18
-
#+CAPTION: Logo van Joeni
19
-
#+NAME:   fig:joeni-logo
20
-
[[./images/joeni-logo.png]]
21
-
22
-
Het logo is duidelijk afgeleid van het logo van de UHasselt. De driehoekjes zijn
23
-
zo geplaatst dat het geheel lijkt op een HTML-element, om het verband als
24
-
webapplicatie aan te duiden.
25
-
26
-
*** UHasselt
27
-
Het logo van de UHasselt is op verschillende plaatsen te vinden op de website.
28
-
De meest prominente locatie is de titelbalk.
29
-
30
-
#+CAPTION: Afbeelding van hoe het logo van de UHasselt in de titelbalk verwerkt is
31
-
#+NAME: fig:uhasselt-titlebar
32
-
[[./img/a.jpg]]
+
1
 Een mooi uitgewerkte huisstijl is essentieel voor het creëren van een gevoel van
+
2
 samenhorigheid met verschillende entiteiten: Ze dienen ter onderscheiding van de
+
3
 rest, en geven een uniforme uitstraling aan de onderdelen op de unief.
+
4
 In Joeni wordt de huisstijl van de UHasselt verder uitgewerkt en gebruikt. In
+
5
 dit hoofdstuk wordt dit in detail uitgelegd, zodat het als basis kan dienen voor
+
6
 andere software.
+
7
+
8
 Ik vermoed dat een deel van de huisstijl simpelweg niet met de studenten mede
+
9
 gedeeld wordt; op de website wordt doorgaans gelinkt naar een "Huisstijl voor
+
10
 studenten", wat doet vermoeden dat er ook een "Huisstijl voor personeel" moet
+
11
 zijn, of iets in die aard.
+
12
+
13
*** Logo
+
14
 Joeni heeft tot doel als vervanging te dienen voor het Studentendossier en
+
15
 BlackBoard. In combinatie met de relatie tot de UHasselt, wordt voor Joeni het
+
16
 volgende logo gebruikt:
+
17
+
18
 #+CAPTION: Logo van Joeni
+
19
 #+NAME:   fig:joeni-logo
+
20
 [[./images/joeni-logo.png]]
+
21
+
22
 Het logo is duidelijk afgeleid van het logo van de UHasselt. De driehoekjes zijn
+
23
 zo geplaatst dat het geheel lijkt op een HTML-element, om het verband als
+
24
 webapplicatie aan te duiden.
+
25
+
26
**** UHasselt
+
27
 Het logo van de UHasselt is op verschillende plaatsen te vinden op de website.
+
28
 De meest prominente locatie is de titelbalk.
+
29
+
30
 #+CAPTION: Afbeelding van hoe het logo van de UHasselt in de titelbalk verwerkt is
+
31
 #+NAME: fig:uhasselt-titlebar
+
32
 [[./img/a.jpg]]
+
33
+
34
 Alhoewel de vorm van de driehoekjes lichtjes afwijkt van het echte logo, valt
+
35
 dit nauwelijks op. Het logo verwerken in de titel is mogelijk, omdat dit gewoon
+
36
 tekst is, meer specifiek, ▶ ~U+25B6 BLACK RIGHT-POINTING TRIANGLE~.
+
37
+
38
 Het voordeel hieraan is niet louter een besparing op bytes.[fn:utf-8] Omdat dit
+
39
 tekst is, zal de betere webbrowser in staat zijn om, afhankelijk van de
+
40
 achtergrond, het logo de juiste kleur te geven. Op de volgende afbeelding is dit
+
41
 effect duidelijk te zien, zeker in contrast met het logo dat de
+
42
 UHasselt-bibliotheek gebruikt.
+
43
+
44
#+CAPTION: Vergelijking tussen logo via UTF-8/tekst en als afbeelding. Merk op hoe het logo van de bibliotheek praktisch onzichtbaar is bij de zwarte achtergrond.
+
45
#+NAME: fig:utf8-better
+
46
[[./img/a.jpg]]
33
47
34
48
Alhoewel de vorm van de driehoekjes lichtjes afwijkt van het echte logo, valt
35
-
dit nauwelijks op. Het logo verwerken in de titel is mogelijk, omdat dit gewoon
36
-
tekst is, meer specifiek, ▶ ~U+25B6 BLACK RIGHT-POINTING TRIANGLE~.
37
-
+
49
 Op de website wordt als [[https://www.uhasselt.be/UH/Help-Studenten-Algemene_Help-Huisstijl/Lettertype.html][lettertype]] Verdana aangereikt. Dit strookt echter niet
+
50
 met het lettertype dat wordt gebruikt in de vele documenten die de UHasselt
+
51
 verspreidt, gaande van informatieboekjes over de studierichtingen tot de
+
52
 spandoeken die buiten aan het universiteitsgebouw worden opgehangen.
+
53
+
54
 Het wordt nergens vermeld, maar dit lettertype gelijkt volledig op
+
55
 [[https://design.ubuntu.com/font/][het Ubuntu-lettertype]], zoals de volgende vergelijking duidelijk aantoont.
+
56
+
57
 #+CAPTION: Vergelijking tussen lettertype gebruikt door UHasselt en Ubuntu-lettertype op voorbeeldtekst
+
58
 #+NAME: fig:font-comparison
+
59
 [[./images/font-comparison.png]]
+
60
+
61
 Dit lettertype wordt doorheen Joeni gebruikt voor het aanduide van belangrijke
+
62
 (kop)teksten.
+
63
38
64
Het voordeel hieraan is niet louter een besparing op bytes.[fn:utf-8] Omdat dit
39
-
tekst is, zal de betere webbrowser in staat zijn om, afhankelijk van de
40
-
achtergrond, het logo de juiste kleur te geven. Op de volgende afbeelding is dit
41
-
effect duidelijk te zien, zeker in contrast met het logo dat de
42
-
UHasselt-bibliotheek gebruikt.
43
-
+
65
 De UHasselt gebruikt in de informatiebrochures wel een kleurenpalet dat eigen
+
66
 lijkt te zijn aan de bepaalde faculteiten, maar verder wordt het haast nergens
+
67
 anders gebruikt. Vermoedelijk komt dit omdat nergens in de huisstijl wordt
+
68
 vermeld welke kleuren gebruikt kunnen worden voor wat.\\
+
69
 Hieronder worden de verschillende kleurwaarden voor elke faculteit uiteengezet.
+
70
 Ze geven een eigen gezicht aan de documentatie binnen elke faculteit, en kunnen
+
71
 makkelijk gebruikt worden voor zowel voor- als achtergrondkleuren.
+
72
+
73
 #+CAPTION: Een kleurenpalet dat gebruikt kan worden voor de huisstijl van de UHasselt verder uit te bouwen
+
74
 #+NAME: fig:color-swatches
+
75
 [[./images/color-swatches.png]]
+
76
44
77
[fn:utf-8] Meestal wordt een logo meegestuurd die langs de titel wordt
45
78
weergegeven in de titelbalk. Dat is niet fout, maar ze zijn wel een stuk groter in het
46
79
aantal bytes. [[https://bibliotheek.uhasselt.be/sites/default/files/favicon.ico][Het logo dat UHasselt gebruikt op haar eigen website]] is 1,150
47
80
bytes groot, [[https://www.fileformat.info/info/unicode/char/25b6/index.htm][▶(×2) is slechts 3(×2) bytes groot]], dus een aanzienlijke verkleining van de
48
81
benodigde ruimte.
49
82
50
-
#+CAPTION: Vergelijking tussen logo via UTF-8/tekst en als afbeelding. Merk op hoe het logo van de bibliotheek praktisch onzichtbaar is bij de zwarte achtergrond.
51
-
#+NAME: fig:utf8-better
52
-
[[./img/a.jpg]]
53
-
54
-
** Lettertype
55
-
Op de website wordt als [[https://www.uhasselt.be/UH/Help-Studenten-Algemene_Help-Huisstijl/Lettertype.html][lettertype]] Verdana aangereikt. Dit strookt echter niet
56
-
met het lettertype dat wordt gebruikt in de vele documenten die de UHasselt
57
-
verspreidt, gaande van informatieboekjes over de studierichtingen tot de
58
-
spandoeken die buiten aan het universiteitsgebouw worden opgehangen.
59
-
60
-
Het wordt nergens vermeld, maar dit lettertype gelijkt volledig op
61
-
[[https://design.ubuntu.com/font/][het Ubuntu-lettertype]], zoals de volgende vergelijking duidelijk aantoont.
62
-
63
-
#+CAPTION: Vergelijking tussen lettertype gebruikt door UHasselt en Ubuntu-lettertype op voorbeeldtekst
64
-
#+NAME: fig:font-comparison
65
-
[[./images/font-comparison.png]]
66
-
67
-
Dit lettertype wordt doorheen Joeni gebruikt voor het aanduide van belangrijke
68
-
(kop)teksten.
69
-
70
-
** Kleuren
71
-
De UHasselt gebruikt in de informatiebrochures wel een kleurenpalet dat eigen
72
-
lijkt te zijn aan de bepaalde faculteiten, maar verder wordt het haast nergens
73
-
anders gebruikt. Vermoedelijk komt dit omdat nergens in de huisstijl wordt
74
-
vermeld welke kleuren gebruikt kunnen worden voor wat.\\
75
-
Hieronder worden de verschillende kleurwaarden voor elke faculteit uiteengezet.
76
-
Ze geven een eigen gezicht aan de documentatie binnen elke faculteit, en kunnen
77
-
makkelijk gebruikt worden voor zowel voor- als achtergrondkleuren.
78
-
79
-
#+CAPTION: Een kleurenpalet dat gebruikt kan worden voor de huisstijl van de UHasselt verder uit te bouwen
80
-
#+NAME: fig:color-swatches
81
-
[[./images/color-swatches.png]]
82
-
[[./images/color-swatches.png]]

docs/thesis/implementatie_uhasselt.org

3 additions and 6 deletions.

View changes Hide changes
1
1
2
2
In de huidige staat is Joeni in staat om BlackBoard in haast zijn volledigheid
3
-
te vervangen; alle functionaliteit die op de universiteit gebruikt wordt van
4
-
BlackBoard, wordt ook aangeboden door Joeni, echter in een formaat dat sneller
5
-
en efficiënter werkt (en ook goedkoper). Joeni heeft ook de meest gebruikte
6
-
onderdelen van het studentendossier ingebouwd (waarvan het uurrooster een mooi
7
-
voorbeeld is).
8
-
+
3
te vervangen. Maar in dit onderdeel wordt hier vanuit gegaan om een eventuele
+
4
overstap naar iets anders te bespreken.
+
5
9
6
BB en het studentendossier afvoeren zal echter niet van vandaag op morgen gaan;
10
7
er blijft nog een hoop functionaliteit niet geïmplementeerd.
11
8
12
9
In dit hoofdstuk wordt aangenomen dat Joeni deze programma's zou vervangen.
13
10
Joeni is vanaf het begin ontworpen in functie van de Universiteit Hasselt. Dit
14
11
was een primaire vereiste om aan te tonen dat een alternatief niet enkel
15
12
mogelijk is, maar ook /bestaat/.
16
13
17
14
In dit hoofdstuk worden de verschillende stappen voor een eventuele
18
15
vervangingsprocedure uiteen gezet, met name hoe dat het beste zou kunnen gebeuren.
19
16
20
17
** Startfase
21
18
In de eerste fase van de vervanging wordt Joeni geïnstalleerd op de servers van
22
19
UHasselt.
23
20
24
21
*** Aankoppelen BB en studentendossier
25
22
Het kan niet verantwoord worden tegen personeelsleden om alle gegevens die ze
26
23
invoeren, verplicht in duplicaat ook in Joeni in te geven. \\
27
24
In plaats daarvan zal er wat extra software geschreven moeten worden, die zich
28
25
gedraagt als /middleman/ tussen Joeni en de andere programma's.
29
26
30
27
Voor het studentendossier zou dit normaal gezien mogelijk moeten zijn; Joeni
31
28
beschikt al over ingebouwde validatiecode, dus alles wat ingegeven wordt op
32
29
Joeni, is gecontroleerd op correctheid.
33
30
34
31
35
32
36
33
BlackBoard is software waar we echter geen controle over hebben; gegeven het
37
34
propriëtaire karakter van de software is het hoogst onwaarschijnlijk dat 
38
35
BlackBoard inc. zijn medewerking zal verlenen om een emigratie van
39
36
hun software te vergemakkelijken, laat staan mogelijk te maken. (UHasselt is in
40
37
dit geval het slachtoffer van [[https://en.wikipedia.org/wiki/Vendor_lock-in][Vendor lock-in]]) \\
41
38
Er blijven hierbij twee opties:
42
39
43
40
- BlackBoard blijven gebruiken :: Joeni wordt in dat geval beperkt tot het
44
41
     vervangen van het studentendossier. In dit geval blijft de UHasselt
45
42
     afhankelijk van een extern bedrijf voor een belangrijk onderdeel van haar
46
43
     opdracht, met alle gevolgen van dien.
47
44
- BlackBoard direct afkoppelen :: Studenten en personeel worden direct
48
45
     overgeschakeld. Deze optie is echter ook niet valabel; er zullen
49
46
     ongetwijfeld dingen ontbreken, en een universiteit kan zich niet
50
47
     permitteren alle opleidingen in gevaar te brengen.
51
48
52
49
Een tussenoplossing lijkt hier aangewezen: \\
53
50
Zoals eerder gezegd bezit Joeni al een hoop van de functionaliteit die
54
51
BlackBoard aanbiedt. Het is misschien gemakkelijker om de overstap faculteit per
55
52
faculteit te doen, of misschien zelfs opleiding per opleiding. In voorkomend
56
53
geval zal dit dan in overleg met alle betrokken partijen besproken worden.
57
54
58
55
** Testfase
59
56
In de testfase wordt Joeni opengesteld voor gebruik. BB en studentendossier
60
57
blijven bestaan en functioneren.
61
58
62
59
De studenten worden nu op de hoogte gesteld van het bestaan van Joeni, en er
63
60
wordt een link aangebracht op de website van de UHasselt, zodat men ernaartoe
64
61
kan navigeren.
65
62
66
63
Studenten en personeel zijn op dit moment vrij om naar eigen welbevinden het
67
64
programma te gebruiken dat voor hen het beste overkomt. Zo kan iedereen op
68
65
zijn/haar eigen tempo de overstap maken.
69
66
70
67
Deze fase is belangrijk om de acceptatie van veranderingen die het ALIPA-project
71
68
teweeg brengt in de hand te werken; naarmate Joeni stabieler en populairder
72
69
wordt, zal iedereen voor zichzelf kunnen bepalen wanneer de tijd rijp is om mee
73
70
te doen aan de verandering.
74
71
75
72
*** Feedback & input
76
73
Sommige gebruikers zullen ongetwijfeld hun mening willen uiten over
77
74
functionaliteit, ideeën aanbrengen, fouten opmerken, ...\\
78
75
Vanzelfsprekend zal er binnen Joeni de mogelijkheid zijn om feedback te geven
79
76
aan de ontwikkelaars.
80
77
81
78
*** Work in progress
82
79
Joeni zal in deze fase constant veranderingen ondergaan; daarom dat er van tijd
83
80
tot tijd werkzaamheden aan zullen plaatsvinden. Dit hoeft echter geen probleem
84
81
te vormen. Aanpassingen kunnen op voorhand aangekondigd worden, en moesten er
85
82
toch onvoorziene fouten optreden, dan kan er nog altijd teruggevallen worden op
86
83
BlackBoard en het studentendossier.
87
84
88
85
** Deployment
89
86
De laatste etappe bestaat uit het afschakelen van de programma's die Joeni wenst
90
87
te vervangen. Het spreekt voor zich dat deze fase slechts kan worden gestart als
91
88
ook alle benodigde functionaliteit overgezet is.
92
89
93
90
Het contract met BlackBoard Inc. kan opgezegd worden. 

docs/thesis/info-processen.org

2 additions and 2 deletions.

View changes Hide changes
1
-
Een ander prominent deel van deze bachelorproef gaat over het verbeteren van
+
1
Een ander prominent deel van deze bachelorproef gaat over het verbeteren van
2
2
bestaande informatieprocessen.
3
3
4
4
*** Reservatie lokalen
5
-
+
5
6
6
7
7
*** COMMENT Studiegids
8
8
Op dit moment wordt de studiegids manueel opgebouwd, waarbij
9
9
docenten/hoogleraren moeten indienen welke voorkennis vereist is, hoe het vak
10
10
gequoteerd wordt, of er een tweede kans is, ...
11
11
12
12
Dit moet ook worden goedgekeurd, waardoor wijzigingen een nogal omslachtige
13
13
procedure volgen. Daarbij lijken de pagina's in de studiegids nogal een andere
14
14
stijl te gebruiken dan de omvattende pagina.

docs/thesis/lokaalreservaties.org

6 additions and 6 deletions.

View changes Hide changes
1
1
Het inplannen van de lokalen op de UHasselt is een complexe opdracht. In het
2
2
onderzoek is naar voren gekomen dat deze opdracht onnodig ingewikkelder wordt
3
3
gemaakt.
4
4
5
5
*** De huidige software
6
6
Het huidige programma blijkt een overblijfsel te zijn van de Economische
7
7
Hogeschool. Sindsdien zijn er geen aanpassingen meer gebeurd, en volgens het
8
8
personeel dat ermee werkt, is dat zeer merkbaar.
9
9
10
10
De broncode is volgens Ilse Saenen geschreven in Delphi, maar ik heb twijfels
11
11
hierbij, want dit strookt niet direct met het feit dat dit programma nog van de
12
12
EHL komt.[fn:chronology] Ik vermoed dat Turbo Pascal gebruikt werd, dit zou dan
13
13
ook verklaren waarom de software op een aparte computer draait.
14
14
15
15
[fn:chronology] De Economische Hogeschool ging op in het Limburgs Universitair
16
-
Centrum eind jaren 80, maar Delphi kwam pas uit in 1995. Misschien zijn er later
17
-
nog wijzigingen gebeurd, maar dat is niet zeker.
18
-
19
-
Het programma vereist ook dat het op een aparte computer wordt gedraaid. Ook dit
20
16
sterkt het vermoeden dat het programma in Turbo Pascal geschreven werd, daar
21
17
deze wel werkt op MS-DOS.
22
18
23
19
Een ander groot probleem is dat het programma gewoon te traag is. Bij te veel
24
20
aanpassingen wordt het onwerkbaar traag, en regelmatig crasht het gewoon.
25
21
26
22
Daarbovenop is de functionaliteit behoorlijk beperkt; alhoewel het wel mogelijk
27
23
is om rekenbladen of foto's uit het programma op te vragen, is simpele tekst
28
24
niet mogelijk.
29
25
30
26
**** Toekomst van het programma
31
27
Ik vermoed dat de huidige software niet meer bruikbaar is; alhoewel een
32
28
programma onderhouden vaak een betere keuze is dan het volledig opnieuw
33
29
schrijven, is het probleem dat dat onderhoud /al twintig jaar uitgesteld is/.
34
30
Voor de gebruikte programmeertaal ervaren programmeurs vinden is op zich al een
35
31
opdracht, en het integreert nu al niet meer met recente besturingssystemen. Mijn
36
32
inziens lijkt het beter dat er wordt uitgekeken naar een andere oplossing. Deze
37
33
opmerking is strijdig met die van de gebruikers van het programma zelf; zij
38
34
hebben de wens geuit dat het programma toch wordt gerepareerd, voornamelijk
39
35
omdat ze dit programma kennen. Misschien dat begeleiding met een nieuw programma
40
36
de overgang naar een eventuele vervanging draagelijker kan maken.
41
37
42
38
**** Alternatieven
43
39
 Dit probleem is niet nieuw; er is al door het personeel zelf gezocht naar
44
40
 mogelijke alternatieve software. Twee voorstellen kwamen prominent naar boven.
45
41
46
42
 Het eerste voorstel is *Porto*, met de Universidade do Porto als toepasselijke
47
43
 origine. Dit werd zelfs proactief aangevoerd door de ontwikkelaars zelf,
48
44
 inclusief een bijbehorend onderhoudscontract voor twee jaar. De prijs bedroeg
49
45
 echter €10000, en dat was te duur.
50
46
51
47
 Het tweede is een combinatie van twee gekoppelde systemen, *Syllabus +
52
48
 Enterprise/Classic*. In tegenstelling tot Porto wordt dit programma al gebruikt
53
49
 op Belgische bodem door de UCLL en KUL. Het bezit veel van de benodigde
54
50
 functies, maar de werking viel niet in goede aarde, alhoewel het personeel zelf
55
51
 vermoedt dat dit een kwestie van smaak is.
56
52
57
53
*** Onthouden
58
54
Een ander groot probleem met lokalen inplannen is dat veel informatie uit het
59
55
hoofd onthouden moet worden. Dit is dan info zoals het aantal zitplaatsen in
60
56
lokalen, de software die op de computers geïnstalleerd staat, ... Deze info kan
61
57
gemakkelijk met de computer onthouden worden, maar dit gebeurd gewoon niet. Dit
62
58
geeft dan ook grote problemen als een personeelslid ziek wordt en tijdelijk
63
59
wegvalt; eventuele vervanging heeft simpelweg geen toegang tot belangrijke info.
64
60
65
61
*** Manuele processen
66
62
Veel zaken die praktisch gezien makkelijk geautomatiseerd kunnen worden,
67
63
vereisen nog steeds veel menselijke interventie. Een externe reservering loopt
68
64
via de Dienst Communicatie, waarbij vooral e-mails gebruikt worden om te
69
65
communiceren met andere personeelsleden. Een gelijkaardig proces geldt voor
70
66
wijzigingen van de docenten uit; zij contacteren het personeel rechtstreeks,
71
67
maar ook via e-mail.
72
68
73
69
Deze processen zijn voor verbetering vatbaar, en voorstellen worden aangevoerd
74
-
in [[Informatieprocessen][het hoofdstuk omtrent informatieprocessen]].
75
-
+
70
# in [[Informatieprocessen][het hoofdstuk omtrent informatieprocessen]].
+
71
76
72
*** In het kort
77
73
78
74
Het is duidelijk dat de manier van hoe lokalen gereserveerd worden toe is aan
79
75
een grondige verbetering. Niet alleen is de ruggengraat van het proces toe aan
80
76
een vervanging (of op z'n minst een grondige revisie), er moet gewerkt worden
81
77
aan manieren om tijdrovend werk om te zetten in geautomatiseerde processen, om
82
78
de kostbare tijd van het personeel effectiever in te zetten.
83
79
84
80
Het volledige rapport is te vinden in [[Vergadering 1][de appendix Vergadering 1]].
85
81
+
82
[fn:chronology] De Economische Hogeschool ging op in het Limburgs Universitair
+
83
Centrum eind jaren 80, maar Delphi kwam pas uit in 1995. Misschien zijn er later
+
84
nog wijzigingen gebeurd, maar dat is niet zeker.
+
85
nog wijzigingen gebeurd, maar dat is niet zeker.

docs/thesis/master.org

3 additions and 2 deletions.

View changes Hide changes
1
1
#+language: nl
2
2
#+latex_class: report
3
3
#+latex_class_options: [a4paper]
4
4
#+latex_header: \usepackage{pdfpages}
5
5
#+latex_header: \usepackage{biblatex}
+
6
#+latex_header: \usepackage{biblatex}
6
7
#+latex_header: \bibliography{sources}
7
8
#+latex_header: \usepackage[dutch]{babel}
8
9
#+OPTIONS: toc:nil
9
10
#+OPTIONS: H:6
10
11
#+author: Maarten Vangeneugden @@latex:\\@@ prof. dr. Wim Lamotte
11
12
#+date: 2017-2018
12
13
#+title: Joeni
13
14
#+subtitle: Bachelorproef voorgedragen tot het behalen van de graad van bachelor in de informatica
14
15
#+TOC: headlines 6
15
16
16
17
#+INCLUDE: "./voorwoord.org"
17
18
18
19
* Onderzoek
19
20
#+INCLUDE: "./uurroosters.org"
20
21
#+INCLUDE: "./lokaalreservaties.org"
21
22
#+INCLUDE: "./examens.org"
22
23
#+INCLUDE: "./inplannen.org"
23
24
#+INCLUDE: "./blackboard.org"
24
25
25
26
* Joeni
26
27
#+INCLUDE: "./softwarekeuzes.org"
27
28
#+INCLUDE: "./beveiliging.org"
28
-
#+INCLUDE: "./client-side-scripting.org"
29
29
#+INCLUDE: "./courses.joeni.org"
+
30
#+INCLUDE: "./courses.joeni.org"
30
31
#+INCLUDE: "./curriculum.joeni.org"
31
32
#+INCLUDE: "./databank.joeni.org"
32
33
#+INCLUDE: "./dienstmededelingen.org"
33
34
#+INCLUDE: "./instellingen.joeni.org"
34
35
#+INCLUDE: "./lokalen.joeni.org"
35
36
#+INCLUDE: "./mededelingen.joeni.org"
36
37
#+BEGIN_COMMENT
37
38
#+INCLUDE: "./postgres.org"
38
39
#+END_COMMENT
39
40
#+INCLUDE: "./rooster.joeni.org"
40
41
#+INCLUDE: "./verbeteringspunten_joeni.org"
41
42
42
43
43
44
44
45
* Informatieprocessen en algemene verbeteringen
45
46
46
47
#+INCLUDE: "./aandachtspunten.org"
47
48
#+INCLUDE: "./info-processen.org"
48
-
#+INCLUDE: "./huisstijl.org"
+
49
#+INCLUDE: "./huisstijl.org"
49
50
#+INCLUDE: "./implementatie_uhasselt.org"
50
51
#+INCLUDE: "./toekomst.org"
51
52
52
53
* Dankwoord
53
54
#+INCLUDE: "./dankwoord.org"
54
55
55
56
56
57
57
58
58
59
59
60
60
61
61
62
62
63
63
64
64
65
65
66
66
67
67
68
68
69
69
70
@@latex:\printbibliography@@
70
71
* Appendices
71
72
#+INCLUDE: "./verslagen.org"
72
73
73
74
74
75
* COMMENT Structuur
75
76
- Titelblad
76
77
- Inhoudsopgave
77
78
- Voorwoord/Inleidende tekst
78
79
- Hoofdstuk 1 - Onderzoek
79
80
- Hoofdstuk 2 - Beschrijving Joeni
80
81
- Hoofdstuk 3 - Voorstellen verbetering UHasselt / Bedachte processen
81
82
- Dankwoord
82
83
- Bibliografie
83
84
- Appendices 

docs/thesis/rooster.joeni.org

4 additions and 5 deletions.

View changes Hide changes
1
1
Het rooster tracht de problemen van [[Uurroosters][de drie bestaande uurroosters]] weg te werken,
2
2
door ze te integreren in één enkele pagina.
3
3
4
4
Wanneer de gebruiker de pagina opent, wordt de huidige week direct
5
5
weergegeven.[fn:weekends] De verschillende vakken worden weergegeven, vergezeld
6
6
van de docent, de locatie, tijdstip en het onderwerp van het evenement
7
7
(bv. hoorcollege).
8
8
9
9
[fn:weekends] Als de student het rooster bekijkt tijdens het weekend, wordt de
10
-
planning voor de volgende week weergegeven.
11
-
12
-
Het volledige uurrooster wordt op de achtergrond in de server gegenereerd, en
13
10
_vereist dus geen JavaScript_. Het resultaat wordt weergegeven in een gewone
14
11
HTML-tabel.
15
12
16
13
Elke rij stelt een kwartier voor. Dit is nodig, omdat een beperking in de
17
14
databank vereist dat evenementen starten en eindigen op kwartieren. Evenementen
18
15
spannen over meerdere rijen middels het ~~rowspan~~-attribuut.
19
16
** TODO Schrijf over waarom kwartieren
20
-
21
17
*** Conflicten
22
18
Het kan gebeuren dat er verschillende evenementen overlappen. Dit wordt
23
19
aangemerkt als een /conflict/. Conflicten worden in felrood en vette tekst
24
20
weergegeven in de tabel, zodat het zeker opvalt. Om mensen met een zwak vermogen
25
21
om kleuren te zien worden tegemoet gekomen met een gestreepte rand.
26
22
27
23
Conflicten worden direct onder de tabel opgelijst, waardoor de student zelf kan
28
24
zien welke evenementen overlappen. De redenering hiervoor is dat het
29
25
overlappende evenementen in de tabel weergeven veel problemen oplevert; omdat er
30
26
maar 1 element kan staan op elke rij- en kolomindex, zou het overlappende
31
27
evenement foutief geplaatst worden (bijvoorbeeld op de volgende dag). Een
32
28
alternatief is om ze toch langs elkaar te zetten, maar dit zou complexere code
33
29
vereisen, en het risico bestaat dat de vakjes te dun worden om goed leesbaar te
34
30
zijn. Uiteindelijk zijn overlappingen ook belangrijke problemen voor de student,
35
31
dus mogen die ook fel opvallen.
36
32
37
33
*** Aanpassingen
38
34
Als er een recente aanpassing is gebeurd, dan wordt dat duidelijk aangegeven in
39
35
de tabel:
40
36
- Geen aanpassing :: Het vakje wordt normaal gekleurd, zonder speciale opmaak.
41
37
- Nieuw evenement :: Het vakje is wit gekleurd, met een zwart gestreepte rand.
42
38
     Dit blijft enkele dagen zo staan.
43
39
- Evenement verplaatst :: Als er een verplaatsing is gedaan van een al bestaand
44
40
     evenement (bv. een ander lokaal, of een ander tijdstip), dan wordt de
45
41
     achtergrond felgeel, met een gestippelde rode rand. Dit is expres zo
46
42
     opvallend gemaakt omwille van het belang dat dit zo goed mogelijk opvalt;
47
43
     anders kunnen studenten hun colleges missen, of aan het foute lokaal
48
44
     aankomen.
49
45
50
46
*** iCal
51
47
Voor studenten die liever een eigen programma gebruiken om hun agenda te
52
48
beheren, wordt een .ics-bestand in iCal-formaat aangeboden. Dit bestand wordt
53
49
bij elke aanvraag gegenereerd (of uit de cache opgevraagd), zodat altijd de
54
50
meest actuele planning beschikbaar is. De links kunnen ook onderling met
55
51
vrienden gedeeld worden.
56
52
57
53
In tegenstelling tot de iCal-bestanden die de UHasselt beschikbaar stelt, zijn
58
54
dit _gepersonaliseerde_ bestanden, en niet die van modeltrajecten. Daarnaast
59
55
wordt gebruik gemaakt van de juiste velden (zoals het lokaal in het
60
56
"location"-veld) om informatie in op te slaan.
61
57
*** Andere weken
62
58
Er zijn knoppen voorzien om naar andere weken te zoeken. Er wordt weliswaar
63
59
steeds aangegeven welke dagen in de week vallen, niet welk "weeknummer" nu
64
60
bekeken wordt.
65
61
*** URL's
66
62
67
-
De URL's die voortkomen uit het rooster zijn makkelijk te manipuleren. Een
+
63
De URL's die voortkomen uit het rooster zijn makkelijk te manipuleren. Een
68
64
voorbeeld:\\
69
65
=https://uhasselt.be/joeni/roster/05-04-2018/10-04-2018=\\
70
66
Als er geen data in de URL staan, wordt de huidige week aangenomen. Indien er
71
67
wel data staan, dan worden de dagen binnen dat bereik in de tabel weergegeven.
72
68
Deze worden meestal automatisch gegenereerd door naar de volgende/vorige weken
73
69
te kijken, maar studenten kunnen ook zelf een bereik ingeven, zonder praktische
74
70
beperkingen.[fn:actual-limits]
75
71
76
72
De URL hoort eenduidig aan te geven wat er wordt weergegeven. Voor het
77
73
Studentendossier wordt de URL
78
74
=https://uhintra02.uhasselt.be/studdosst/sdsUurrooster.aspx= gebruikt. Maar
79
75
omdat alles met JavaScript wordt afgehandeld, verandert deze URL niet. Dat maakt
80
76
het gebruik van bladwijzers (behalve voor de huidige week) nutteloos, en het
81
77
schrijven van programma's die de agenda uitlezen stukken complexer dan nodig
82
78
83
79
[fn:actual-limits] De enige beperkingen worden opgegeven door het begin van de
84
80
tijd die Python kan weergeven, en het feit dat de eerste datum moet plaatsvinden
85
81
vóór de tweede datum. Maar deze beperkingen spreken zo voor zichzelf dat ze
86
82
evengoed stilgezwegen kunnen worden.
87
83
+
84
[fn:weekends] Als de student het rooster bekijkt tijdens het weekend, wordt de
+
85
planning voor de volgende week weergegeven.
+
86
planning voor de volgende week weergegeven.

docs/thesis/softwarekeuzes.org

148 additions and 30 deletions.

View changes Hide changes
1
-
In dit hoofdstuk wordt dieper ingegaan op de verantwoording voor de gekozen
2
-
software, en worden de mogelijke alternatieven besproken.
3
-
** Softwareframework
4
-
*** Django
+
1
 In dit hoofdstuk wordt dieper ingegaan op de verantwoording voor de gekozen
+
2
 software, en worden de mogelijke alternatieven besproken.
+
3
*** Django
5
4
Voor het schrijven van Joeni heb ik uitgesproken gebruik gemaakt van
6
5
[[https://www.djangoproject.com/][het Django-framework]].
7
6
**** Webframework
8
7
Django is een framework gericht op het ontwikkelen van websites. Omdat Joeni
9
8
hoort te dienen als een directe vervanging voor het Studentendossier en
10
9
BlackBoard, zou een website bouwen de overgang het gemakkelijkst laten gebeuren.
11
10
**** Object-relational mapper
12
11
Het was vanaf het begin al duidelijk dat Joeni een databank zou gaan bevatten,
13
12
compleet met tabellen, vreemde sleutels en voorwaarden.
14
-
+
13
Als er gebruik wordt gemaakt van PHP, worden de SQL-queries vaak /hardcoded/ in
+
14
de broncode opgenomen. Dit is redelijk gevoelig voor fouten in de code, en stelt
+
15
de databank open aan SQL-injecties[fn:PDO].
+
16
+
17
Django biedt aan de ontwikkelaar een object-relational mapper aan, die het
+
18
mogelijk maakt voor de gebruiker om in de taal waarin geprogrammeerd wordt, te
+
19
communiceren met de databank. Een andere handige feature, is dat de data die
+
20
ontvangen wordt van een bepaald type is, een dat op voorhand vastligt. Deze
+
21
types kunnen ook direct in het /template/ gebruikt worden.
+
22
+
23
**** Templates
+
24
Informatie in HTML-pagina's wordt gedeeltelijk direct in de HTML-bestanden
+
25
getypt, maar data van de server moet daarin verwerkt worden op een of andere
+
26
manier. In PHP gebeurt dat door PHP-code tussen de HTML-pagina's te verwerken,
+
27
Django gebruikt templates. Dit is ook een veel properder systeem dan
+
28
programmacode in HTML te verwerken; het helpt om het visuele aspect (GUI) van de
+
29
achterliggende code te scheiden (Backend/Python).
+
30
+
31
**** COMMENT Ingebouwde beveiliging
+
32
Veelvoorkomende beveiligingsproblemen bij webapplicaties worden automatisch
+
33
afgehandeld in Django. Er is beveiliging tegen CSRF, XSS, clickjacking,
+
34
SQL-injecties en automatische HTTPS-redirects. Al die bescherming laat de
+
35
programmeur toe om zich toe te leggen op het programma zelf, zonder een risico
+
36
te lopen dat er veiligheidslekken ontstaan.[fn:purpose]
+
37
+
38
[fn:purpose] Deze beveiliging vereist wel dat er niet actief gevaarlijke code
+
39
geschreven wordt, maar een gemiddelde kennis van programmeren is hiervoor al
+
40
voldoende. Code zoals 
+
41
~~ kan nooit adequaat
+
42
beveiligd worden als /user-submitted data/ in ~link~ terecht kan komen.
+
43
+
44
15
45
*** Python (3)
16
46
Alhoewel er wel voor elke programmeertaal één of meerdere frameworks voor het
17
47
maken van websites bestaan, ging de voorkeur uit naar Python.
18
48
19
49
Python is een dynamische, sterk getypeerde programmeertaal 
20
-
21
-
*** UTF-8
22
-
Joeni maakt uitsluitend gebruik van UTF-8 voor encodering van tekst.\\
23
-
Niet alleen is dit standaard voor strings in Python 3, het laat ook toe om het
24
-
logo van de UHasselt in de titelbalk te verwerken, en zorgt ervoor dat alle
25
-
teksten correct gespeld en opgeslagen kunnen worden.  
26
-
Dit is ook handig voor Erasmusstudenten met vreemde namen zoals bv. 
27
-
"Kürt Pðovski", die hun echte naam kunnen gebruiken, zonder substituties te
28
-
moeten gebruiken voor bepaalde tekens.
29
-
30
-
* Andere mogelijkheden
31
-
Tegenover de gemaakte keuzes staan ook een hoop alternatieven die niet werden
32
-
gebruikt. 
33
-
** Ruby (on Rails)
34
-
Mijn ervaring met Ruby is simpelweg onbestaande; ik heb nooit in deze taal
35
-
geprogrammeerd. De beperkte tijd die ik had voor de bachelorproef stond niet toe
36
-
dat ik mij nog zou verdiepen in een nieuwe programmeertaal.
37
-
** PHP
38
-
Ongetwijfeld een van de meest gebruikte talen voor het schrijven van dynamische
39
-
websites.\\
40
-
Het probleem is compleet het tegenovergestelde van [[Ruby (on Rails)][Ruby]]; PHP ken ik zeer goed.
41
-
Het is daarom dat ik dit niet beschouw als een goede keuze; de taal zit vol met
42
-
beveiligingslekken, vertoont extreem raar gedrag dat niet voorkomt in andere
43
-
talen,
44
-
+
50
bespreek ik waarom deze features voordelen zijn voor het gebruik in Joeni.
+
51
+
52
**** Dynamisch
+
53
Het dynamische aspect van Python betekent dat variabelen elk type kunnen
+
54
aannemen. Fouten met de types worden pas opgevangen als de code
+
55
daadwerkelijk uitgevoerd wordt.
+
56
+
57
Toch is de dynamiek juist een voordeel van Python bij Joeni: De variabelen
+
58
zijn niet aan een bepaald type verbonden, en de code maakt vaak duidelijk genoeg
+
59
met welk type omgegaan wordt. Daarnaast zou het constant declareren van types de
+
60
code aanzienlijk groter maken.[fn:inference] Voor Joeni was het belangrijk dat
+
61
er met zo weinig mogelijk code zoveel mogelijk functionaliteit bereikt wordt. De
+
62
voordelen die statisch typeren met zich meebrengt, zouden dit tegenwerken. Ook
+
63
een "hogere snelheid"[fn:speed] is niet nodig, Python 3 is snel genoeg voor de opdracht.
+
64
+
65
Daarbij zijn veel statische talen niet zo handig als op het eerste zicht lijkt.
+
66
Talen zoals Java hebben bijvoorbeeld ~null~, en elke variabele kan de waarde
+
67
~null~ aannemen, wat nogal frustrerend is, want het betekent dat je niet kunt
+
68
vertrouwen op je types, zowat het hele idee aan een statisch typesysteem.
+
69
+
70
[fn:inference] Sommige statische talen zoals Haskell en Rust proberen het
+
71
constant aangeven van types wat te omzeilen met /type inference/, waarbij types
+
72
contextueel worden bepaald.
+
73
+
74
[fn:speed] Statische talen worden vaak als "sneller" omschreven dan dynamische
+
75
talen, omdat de compiler op voorhand optimalisaties zou kunnen uitvoeren. Het is
+
76
maar de vraag in welke mate deze snelheidswinst nog goed opvalt in 2018.
+
77
+
78
**** UTF-8
+
79
 Joeni maakt uitsluitend gebruik van UTF-8 voor encodering van tekst.\\
+
80
 Niet alleen is dit standaard voor strings in Python 3, het laat ook toe om het
+
81
 logo van de UHasselt in de titelbalk te verwerken, en zorgt ervoor dat alle
+
82
 teksten correct gespeld en opgeslagen kunnen worden.  
+
83
 Dit is ook handig voor Erasmusstudenten met vreemde namen zoals bv. 
+
84
 "Kürt Pðovski", die hun echte naam kunnen gebruiken, zonder substituties te
+
85
 moeten gebruiken voor bepaalde tekens.
+
86
+
87
 Een hoop andere talen die voor het web gebruikt worden (zoals PHP en Perl) zijn
+
88
 enkel goed betrouwbaar met ASCII, en dat zou dus zeker problemen opleveren.
+
89
 Joeni gebruikt zelfs emoji als symbolen op sommige plaatsen.
+
90
+
91
**** Ervaring
+
92
Het is een taal waar ik veel ervaring mee heb. Ik ben vooral bekend met
+
93
functionele talen, maar die zijn volgens mij niet echt handig hier.
+
94
([[Lisp, Haskell, ML, Prolog]])
+
95
+
96
De ervaring was een belangrijke factor, omdat het leren van een nieuwe
+
97
programmeertaal voor Joeni niet aan de orde was. Met Python had ik het meeste
+
98
ervaring wat betreft procedurele talen, en dus heb ik ook daarvoor gekozen.
+
99
+
100
*** Andere mogelijkheden
+
101
  Tegenover de gemaakte keuzes staan ook een hoop alternatieven die niet werden
+
102
  gebruikt. Deze worden hier toegelicht.
+
103
**** Ruby (on Rails)
+
104
  Mijn ervaring met Ruby is simpelweg onbestaande; ik heb nooit in deze taal
+
105
  geprogrammeerd. De beperkte tijd die ik had voor de bachelorproef stond niet toe
+
106
  dat ik mij nog zou verdiepen in een nieuwe programmeertaal.
+
107
**** PHP
+
108
  Ongetwijfeld een van de meest gebruikte talen voor het schrijven van dynamische
+
109
  websites.\\
+
110
  Het probleem is compleet het tegenovergestelde van [[Ruby (on Rails)][Ruby]]; PHP ken ik zeer goed.
+
111
  Het is daarom dat ik dit niet beschouw als een goede keuze; de taal zit vol met
+
112
  beveiligingslekken, vertoont extreem raar gedrag dat niet voorkomt in andere
+
113
  talen, er is geen standaardondersteuning voor UTF-8, en dat probleem alleen al
+
114
  veroorzaakt een hoop extra valkuilen en code die met Python gewoon niet nodig zijn.
+
115
+
116
Het wordt ook vaak een "taal voor het web", maar voor een taal die dat als
+
117
primaire sterkte opnoemt, heeft het verdacht weinig features om web development
+
118
te vergemakkelijken. Er is geen template-systeem, geen bescherming tegen XSS of
+
119
CSRF, de programmeur moet manueel een authenticatiesysteem bouwen, de URL is
+
120
exact hetzelfde als je bestandssysteem, en geen mogelijkheid voor een
+
121
"development server". Al deze onderdelen die praktisch élke webapplicatie nodig
+
122
heeft, zit niet in PHP.
+
123
+
124
PHP is een zwakke taal, en zal regelmatig een vreemde conversie uitvoeren dan
+
125
het programma te laten crashen, en de fout aan te wijzen. Zeker
+
126
[[https://habnab.it/php-table.html][bij vergelijken]] is dat een zichtbaar probleem. Er is wel ~===~ om dit op te
+
127
vangen, maar dat werkt niet voor objecten. Zo is er wel altijd iets aan elke
+
128
tool in de PHP-kist.
+
129
+
130
De taal is op sommige plaatsen ook maar een zeer dun laagje over C, op manieren
+
131
  die echt niet helpen voor web development:
+
132
- Veel functies zijn zéér dunne wrappers rond hun onderliggende C-functies:
+
133
  ~dba_nextkey~ geeft een =SEGFAULT= als ~dba_firstkey~ niet eerst opgeroepen
+
134
  wordt.
+
135
- "Out"-parameters[fn:out] zoals in C, ook al heeft PHP ondersteuning voor het
+
136
  teruggeven van meerdere argumenten
+
137
- Zaken die helemaal geen /global behaviour/ vereisen zoals verbinden met MySQL.
+
138
  In C is dat moeilijk te vermijden, maar PHP kan dat wel, en doet het niet.
+
139
+
140
Ik heb ervaring met PHP, en ik ben dus ook op de hoogte van deze problemen. En
+
141
Python heeft zelf ook enkele valkuilen waar je als programmeur op moet letten.
+
142
Maar PHP is bijna ongeëvenaard in het aantal valkuilen, en dus absoluut niet
+
143
geschikt als taal voor het ontwikkelen van webapplicaties.
+
144
+
145
[fn:out] In C is het niet mogelijk om meer dan 1 waarde terug te geven bij een
+
146
functie-aanroep. Je kunt hier omheen werken door /pointers/ naar variabelen als
+
147
parameters mee te geven in de functie zelf, en daar operaties op uit te voeren.
+
148
+
149
**** Lisp, Haskell, ML, Prolog
+
150
De familie van programmeertalen die een meer declaratieve aanpak gebruiken, zijn
+
151
volgens mij niet de beste keuze voor een webserver.\\
+
152
Ik ben namelijk van de indruk dat de code voor een website gemakkelijker te
+
153
begrijpen en te schrijven is in een procedurele vorm, waarin per /request/ een
+
154
lijst van instructies worden afgelopen, waarna een antwoord teruggestuurd wordt.
+
155
In functionele en logische talen is iets proceduraal uitvoeren een stuk
+
156
moeilijker, omdat het fundamenteel ingaat tegen het idee van declaratief
+
157
programmeren. Het zou de code alleen maar "onnatuurlijk" doen aanvoelen. Een
+
158
programmeertaal dient behulpzaam te zijn, en deze talen zijn geschikt voor
+
159
andere taken, maar niet voor Joeni.
+
160
45
161
[fn:PDO] Het is wel mogelijk om SQL-injecties redelijk te voorkomen als gebruik
+
162
wordt gemaakt van PDO, maar dit is niet standaard in PHP.
+
163
wordt gemaakt van PDO, maar dit is niet standaard in PHP.

docs/thesis/sources.bib

2 additions and 2 deletions.

View changes Hide changes
1
1
author = "UHasselt",
2
2
title  = "Q\&A ALIPA",
3
3
year   = "2017",
4
4
number = "1",
5
5
journal = "Nu weet je het",
6
6
pages  = "4-5",
7
7
url    = "https://www.uhasselt.be/documents/Tijdschriften/nUweetjeHet/personeelsblad-februari-2017-klein.pdf"
8
8
}
9
9
10
10
@article{jaarverslag-2017,
11
11
author = "UHasselt",
12
12
title  = "2017 in cijfers",
13
13
year   = "2017",
14
14
journal  = "Jaarverslag 2017",
15
15
pages  = "6",
16
16
url    = "https://www.uhasselt.be/Documents/UHasselt/algemeen/jaarverslagen/2017/jaarverslag-2017.pdf"
17
17
}
18
18
19
19
@article{strafwetboek-valsheid-informatica,
20
20
author = "Belgische federale regering",
21
21
title  = "Strafwetboek/Code pénal",
22
22
chapter= "IV",
23
23
series = "IIbis",
24
24
number = "Artikel 210bis",
25
25
url   = "http://www.ejustice.just.fgov.be/cgi_loi/loi_a1.pl?language=nl&la=N&cn=1867060801&table_name=wet&&caller=list&fromtab=wet&tri=dd+AS+RANK#LNK0052"
26
26
}
27
27
28
28
@article{gnu-saass,
29
29
author = "dr.h.c.mult. Richard M. Stallman",
30
30
title  = "Who does that server really serve?",
31
31
url    = "https://www.gnu.org/philosophy/who-does-that-server-really-serve.html"
32
32
}
33
33
34
34
@report{eu-gdpr,
35
35
url   = "https://eur-lex.europa.eu/eli/reg/2016/679/oj",
36
36
title = "REGULATION (EU) 2016/679 OF THE EUROPEAN PARLIAMENT AND OF THE COUNCIL of 27 April 2016",
37
37
subtitle = "on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation)",
38
38
date = "2016-04-27",
39
39
author = "European Parliament, Council of the European Union"
40
40
}
41
41
42
42
@online{bb-tos,
43
43
url   = "http://www.blackboard.com/legal/terms-of-use.html",
44
44
title = "Terms Of Use"
45
45
}
46
46
47
47
@online{bb-privacy-policy,
48
-
title = "Blackboard Privacy Statement",
+
48
title = "Blackboard Privacy Statement",
49
49
date  = "2018-05-24",
50
50
url   = "https://www.blackboard.com/legal/privacy-policy.html"
51
51
}
52
52
53
53
@article{bb-blackout,
54
-
url   = "https://web.archive.org/web/20101115105111/http://blogs.palmbeachpost.com/extracredit/2008/04/18/blackboard-blackout/",
+
54
url   = "https://web.archive.org/web/20101115105111/http://blogs.palmbeachpost.com/extracredit/2008/04/18/blackboard-blackout/",
55
55
author = "Kim Miller",
56
56
title = "Blackboard Blackout",
57
57
date = "2008-04-18"
58
58
}
59
59
60
60
@article{bb-blackout2,
61
61
url   = "https://web.archive.org/web/20110926094431/http://media.www.thehunterenvoy.com:80/media/storage/paper1327/news/2009/02/18/News/Portal.Problems.Blackboard.Blackout-3635795.shtml",
62
62
author = "Jonathan Jordan",
63
63
date = "2009-02-18",
64
64
title = "Portal Problems, Blackboard Blackout",
65
65
subtitle = "Data Systems at CUNY Malfunction and Disrupt Classes"
66
66
}
67
67
68
68
@article{bb-crash,
69
69
url   = "http://itintheuniversity.blogspot.com/2007/11/in-recent-chronicle-article-outlining.html",
70
70
author = "Luke Fernandez",
71
71
title = "Blackboard catastrophic system crash in Utah",
72
72
date = "2007-11-27"
73
73
}
74
74
75
75
@article{bb-dataloss,
76
76
url   = "http://bpeacock22.blogspot.com/2009/01/great-blackboard-crash-of-09.html",
77
77
title = "The Great Blackboard Crash of 09",
78
78
author = "Benjamin s.s.t.t.",
79
79
date = "2009-01-21"
80
80
}
81
81
82
82
@online{ufora,
83
83
url   = "https://www.ugent.be/nl/actueel/lms-ufora.htm",
84
84
title = "De nieuwe Minerva heet Ufora",
85
85
author = "Universiteit Gent",
86
86
date = "2018-06-17"
87
87
}
88
88
89
89
@online{opleiding-informatica,
90
90
url   = "https://www.uhasselt.be/documents/BROCHURES/2018-2019/Master-Informatica-2018-web.pdf",
91
91
title = "Master in de Informatica",
92
92
year = "2018",
93
93
author = "Universiteit Hasselt"
94
94
}
95
95

docs/thesis/toekomst.org

62 additions and 2 deletions.

View changes Hide changes
1
1
 Joeni is op dit moment een voorbeeld van een kant-en-klare oplossing voor de problemen die
2
2
 BlackBoard en het studentendossier stellen aan de UHasselt.
3
3
4
4
 Maar software is steeds in beweging, en is nooit af. Daarom dat ik hier enkele
5
5
 punten voorzie omtrent de toekomstige uitbreidingen die aan Joeni zouden kunnen
6
6
 worden toegevoegd, of aan eender welk ander programma dat als vervanging zou dienen.[fn:still-joeni]
7
7
8
8
[fn:still-joeni] Voor het schrijfgemak wordt in dit hoofdstuk gewoon "Joeni"
9
9
gebruikt om "een vervangende applicatie" te beschrijven, alhoewel dit eender welk
10
10
ander programma kan zijn. Indien het specifiek om Joeni gaat, zal dit ook
11
11
duidelijk blijken uit de context.
12
12
13
13
*** /Desktop/-applicatie
14
14
 Op dit moment wordt Joeni gebruikt via een webbrowser, maar dit is zeker niet
15
15
 wat het eindpunt zou moeten zijn.
16
16
17
17
 Een website kan onmogelijk gebruik maken van alle mogelijkheden die computers
18
18
 aan hun gebruikers bieden; ze zijn van nature statische tekstbestanden, die
19
19
 enkel informatie kunnen doorsturen, en (gestructureerd) via speciale
20
20
 HTML-formulieren informatie kunnen opvangen. Daar komen dan ook een hoop
21
21
 beveiligingsproblemen bij kijken, die inherent zijn aan websites.
22
22
23
23
 Joeni moet een programma worden dat op de computer zelf draait. Veel features
24
24
 die nu simpelweg niet mogelijk zijn in Joeni, zouden hiermee wel mogelijk
25
25
 worden:
26
26
- Pop-ups die aangeven als er een wijziging is gebeurd in het uurrooster :: Nu
27
27
     moeten studenten zelf naar die webpagina surfen, er wordt geen proactieve
28
28
     melding hiervan gemaakt. Veel agendaprogramma's geven hier ook geen melding
29
29
     van, dus via iCal zal dit ook niet lukken.
30
30
- Live chat :: Dit is meer een feature die naar Agora toe gericht is, maar een
31
31
               live chat is ook technisch niet mogelijk zonder /client-side
32
32
               scripting/. Dit zou een uiterst handige toepassing zijn voor
33
-
               groepswerken, waarvoor studenten nu nog altijd zijn aangewezen op
+
33
               Dit zou een uiterst handige toepassing zijn voor
+
34
               groepswerken, waarvoor studenten nu nog altijd zijn aangewezen op
34
35
               programma's van derden.
35
36
- Offline halen van studiemateriaal :: Het is triviaal, maar Joeni werkt enkel
36
37
     met een internetverbinding, net zoals *elke webapplicatie van de UHasselt*.
37
-
     Een "echt" programma kan al het studiemateriaal, meldingen, opdrachten, ...
+
38
     Een "echt" programma kan al het studiemateriaal, meldingen, opdrachten, ...
38
39
     downloaden op de computer van de student, zodat dit altijd offline
39
40
     geraadpleegd kan worden. Het indienen van taken kan dan ook offline
40
41
     gebeuren, waarna het programma zelf bij de eerstvolgende netwerkverbinding
41
42
     de taak doorstuurt.
42
43
- Veel betere samenhang/snelheid :: Een webapplicatie impliceert dat alle pagina's
43
44
     telkens opnieuw moeten worden ingeladen, er zit dus altijd een soort van
44
45
     /delay/ tussen een klik van de gebruiker en de uiteindelijke reactie. De
45
46
     browser moet ook alles inladen en /renderen/, dus een supersnelle cache
46
47
     alleen zal nooit het snelheidsprobleem kunnen oplossen. En als de
47
48
     verbinding wegvalt tijdens het inladen, dan is Joeni plots niet meer
48
49
     bereikbaar, redelijk frustrerend. Een programma op de computer zelf heeft
49
50
     al deze problemen niet. Er kan ook gebruik gemaakt worden van een hoop
50
51
     andere /widgets/ (zoals tabs in hetzelfde venster) die de samenhang verder
51
52
     kunnen verhogen.
52
53
- Dynamische/Directe informatie :: Als de gebruiker een fout maakt bij de
53
54
     interactie met de website, dan kan hier pas melding van worden gemaakt als
54
55
     de pagina opnieuw wordt ingeladen. Met een applicatie op de computer kunnen
55
56
     direct meldingen worden gegeven, en kan het indienen onmogelijk worden
56
57
     gemaakt totdat de gebruiker alle problemen heeft opgelost. Het geeft ook
57
58
     zekerheid: Als een knop wordt ingedrukt, dan is er zekerheid dat de
58
59
     verandering correct werd doorgevoerd.
59
60
+
61
     wordt de eigenaar van een account geverifieerd middels een stamnummer en
+
62
     een wachtwoord. Vergeleken met assymetrische sleutels is dit een redelijk
+
63
     slechte manier van beveiliging. Het WWW is niet voorzien op ergonomisch
+
64
     gebruik van bv. PGP-sleutels, maar een gewoon programma kan hiermee
+
65
     probleemloos overweg.
+
66
60
67
De reden dat er voor Joeni toch gekozen is voor een webapplicatie om te
61
68
beginnen, is omdat het niet zozeer de bedoeling was dat Joeni "het eindpunt" zou
62
69
worden, maar eerder een voorstelling van hoe het eruit zou kunnen zien. Het zou
63
70
Joeni ook complexer maken: Rekening houden met dynamische veranderingen, pop-ups
64
71
inbouwen (waarvan de API's kunnen verschillen per besturingssysteem), ... Het
65
72
maakt het geheel veel moeilijker om te bouwen, maar voegt weinig toe voor deze bachelorproef.
66
73
Daarom dat een website het idee van Joeni veel beter overbrengt, maar dan wel in
67
74
een statische setting.\\
68
75
Daarbij is een groot deel van de code in de achtergrond (voornamelijk de
69
76
databasecode) overdraagbaar, daar een desktopapplicatie sowieso contact zal
70
77
moeten onderhouden met een databank.
71
78
+
79
*** Herschrijven of onderhouden?
+
80
Persoonlijk heb ik bij het zien van bepaalde systemen vaak een indruk van: "Dit
+
81
kan beter, en ik weet hoe." Vermoedelijk bestaat er eenzelfde gevoel bij andere
+
82
informatici, een drang om iets volledig te herschrijven en "het deze keer goed
+
83
te doen".
+
84
+
85
Maar eigenlijk moet voor elk onderdeel apart overwogen worden wat op lange
+
86
termijn het voordeligst is voor de universiteit zelf. Herschrijven is
+
87
aantrekkelijk, maar kan veel tijd kosten en kan onvoorziene fouten met zich
+
88
meebrengen. In het ergste geval staat de software hierna zelfs geen stap verder.
+
89
Daarnaast is het op z'n minst een beetje arrogant om aan te nemen dat we niet zo
+
90
slecht zijn in het programmeren als onze voorganger(s), iedereen maakt immers fouten.
+
91
+
92
Het alternatief is de bestaande software onderhouden. Dit kan voordeliger zijn,
+
93
voor verschillende redenen:
+
94
- Personeel dat de software gebruikt is ermee bekend, en kan gradueel de
+
95
  evolutie ervan meevolgen, alsook direct feedback geven. Bij een /full rewrite/
+
96
  is het altijd wachten tot het klaar is, of totdat er een "MVP"[fn:mvp] bestaat, en dan
+
97
  nog is het veelal giswerk, getuige de leerstof van het vak Software
+
98
  Engineering.
+
99
- Een beetje triviaal, maar toch: De software is al uitvoerig getest, is al
+
100
  grotendeels af, en bestaande problemen zijn goed gekend. Er is geen nood aan
+
101
  het maken van uitvoerige /use cases/, /working drafts/, ... Dat op zich is ook
+
102
  al een enorme hoeveelheid tijd bespaard.
+
103
- Er is een redelijke kans dat deze optie een stuk goedkoper uitvalt dan het
+
104
  volledig opnieuw schrijven.
+
105
+
106
Echter, er zijn enkele voorwaarden aan verbonden:
+
107
- De software moet vrij zijn[fn:private-is-free], anders kan er technisch (en juridisch) gezien geen
+
108
  aanpassing aan gebeuren.
+
109
- De software moet ondersteund worden door de gebruikte systemen. Bijvoorbeeld:
+
110
  Een programma geschreven in Turbo Pascal kan waarschijnlijk niet meer werken
+
111
  op een modern besturingssysteem, terwijl een programma dat op de Java Virtual
+
112
  Machine werkt juist nog een lang leven beschoren kan zijn.
+
113
- Er moeten programmeurs voor te vinden zijn. Hiermee doel ik op het feit dat
+
114
  programmeertalen komen en gaan, en zo ook de interesse van mensen om zich
+
115
  erin te verdiepen: Het is tegenwoordig een stuk moeilijker om een
+
116
  COBOL-programmeur te vinden dan een Javaprogrammeur. Als het vinden van
+
117
  gekwalificeerd personeel te moeilijk is, dan is onderhoud waarschijnlijk
+
118
  gewoon niet meer mogelijk.
+
119
+
120
Een mogelijk voorstel is om een lijst op te stellen van beslissende factoren,
+
121
samen met de juiste personen. Dan kunnen die factoren getoetst worden aan alle
+
122
gebruikte software voor de UHasselt, en dan kan er individueel beslist worden
+
123
welke software vervangen wordt, en dewelke onderhouden wordt.
+
124
+
125
[fn:mvp] /Minimum Viable Product/: Een marketingterm waarmee een prototype van
+
126
een product of werk wordt bedoeld waarmee de klant een eerste indruk kan krijgen
+
127
van het uiteindelijke geheel.
+
128
+
129
[fn:private-is-free] Software die de UHasselt zelf geschreven heeft, is per
+
130
definitie ook vrij.
+
131
definitie ook vrij.

docs/thesis/uurroosters.org

4 additions and 4 deletions.

View changes Hide changes
1
1
Alle studenten beschikken over uurroosters die informatie verschaffen omtrent
2
2
hun weekplanning. Er zijn echter verschillende problemen met het huidige
3
3
systeem.
4
4
5
5
*** 3 verschillende systemen
6
6
In plaats van dat er één uurrooster is dat de meest relevante informatie
7
7
weergeeft, zijn er een hoop verschillende manieren om aan het rooster te
8
8
geraken.
9
9
**** Gewone uurroosters
10
10
Op [[https://collegeroosters.uhasselt.be][deze pagina]] moeten studenten hun faculteit
11
11
ingeven[fn:why-sit], daarop hun academiejaar, en dan het nummer van de week
12
12
die ze willen inkijken. Daarop wordt een "interactieve" gif-afbeelding
13
13
ingeladen waarop de uren van een modeltraject worden weergegeven.
14
14
15
15
[fn:why-sit] Om een onbekende reden wordt de studierichting Informatica apart
16
-
geklasseerd onder de faculteit "SIT", maar dit is onjuist; deze studierichting
17
-
valt onder de faculteit Wetenschappen.
18
-
19
-
Dit systeem heeft verschillende problemen:
20
16
- Werkt niet zonder JavaScript :: Alhoewel dit makkelijk zonder JS kan werken,
21
17
     werkt de website niet als scripts uitgeschakeld zijn. [[(Geen) Gebruik van /client-side scripting/][Dat vormt een probleem]].
22
18
- Weeknummers i.p.v. gewone data :: Ik ken geen mensen die bijhouden welke week
23
19
     van het jaar het is. We houden wel bij welke dag het is, en de meesten
24
20
     plannen ook in op dagen.
25
21
- Opent niet automatisch op huidige week :: Veelal wordt het uurrooster gecheckt
26
22
     omdat men wilt weten wat er deze week gebeurd.
27
23
- HTML én PDF :: Men kan zowel een HTML-pagina openen, als een PDF-bestand.
28
24
                 Waarom dat nodig is is niet geweten, maar het maakt de
29
25
                 achterliggende applicatie wel complexer om te onderhouden.
30
26
- Enkel modeltraject :: Veel studenten volgen een GIT-traject, maar zij moeten
31
27
     met dit systeem vaak 2 á 3 keer opnieuw het proces doorlopen om
32
28
     verschillende uurroosters zelf naast elkaar te leggen.
33
29
- Niet up-to-date :: Uit het onderzoek 
34
30
     [[Vergadering 1][bleek dat dit uurrooster niet up-to-date is, en slechts 1 keer per dag wordt vernieuwd]].
35
31
     Zeker bij snelle wijzigigen voor bv. gastcolleges is dit uurrooster onbetrouwbaar.
36
32
Kleine opmerking bij het iCal-bestand dat op de pagina staat: Alhoewel de
37
33
iCal-specificatie velden specifieert voor locatie, wordt alle informatie over
38
34
een bepaalde gebeurtenis in de titel van het evenement geplaatst.
39
35
**** Dynamische uurroosters
40
36
[[https://uhintra03.uhasselt.be/uurroosters/][Deze uurroosters]] Zijn een directe verbetering op de [[Gewone uurroosters][gewone uurroosters]]; ze zijn
41
37
up-to-date, openen op de huidige week en geven slechts 1 resultaat (een
42
38
HTML-pagina). De resterende problemen blijven echter bestaan.
43
39
**** Uurrooster Studentendossier
44
40
Er is ook de mogelijkheid om een gepersonaliseerd uurrooster op te vragen
45
41
[[https://uhintra02.uhasselt.be/studdosst/sdsUurrooster.aspx][via het studentendossier]]. Deze geeft wél een GIT-traject, maar is nogal
46
42
omslachtig om te bereiken en ziet er erg gedateerd uit. Er is ook geen
47
43
mogelijkheid om een iCal-bestand te verkrijgen, dus voor de meest relevante
48
44
informatie moeten studenten steeds naar deze website surfen. Doordat het
49
45
JavaScript vereist is een simpele /web scraper/ schrijven ook niet echt triviaal
50
46
om te doen.
51
47
**** Nood aan eengemaakt systeem
52
48
Wat op dit moment bestaat is ontoereikend voor de vereisten van de studenten. De
53
49
systemen zijn omslachtig, complex en ze voelen gedateerd aan (en zijn dat ook).
54
50
Daarnaast is drie verschillende applicaties onderhouden sowieso gecompliceerder
55
51
dan maar ééñ onderhouden.
56
52
57
53
In Joeni wordt dan ook een eengemaakt uurrooster voorgesteld, dat poogt al deze
58
54
problemen op te lossen.
59
55
+
56
[fn:why-sit] Om een onbekende reden wordt de studierichting Informatica apart
+
57
geklasseerd onder de faculteit "SIT", maar dit is onjuist; deze studierichting
+
58
valt onder de faculteit Wetenschappen.
+
59
valt onder de faculteit Wetenschappen.

docs/thesis/verbeteringspunten_joeni.org

28 additions and 0 deletions.

View changes Hide changes
1
1
Alhoewel Joeni wel degelijk een positieve invloed kan hebben op de
2
2
IT-infrastructuur van UHasselt, zijn er nog steeds enkele punten die een
3
3
beperking kunnen opleveren. Deze punten worden in dit hoofdstuk toegelicht.
4
4
*** Algemeen
5
5
*Joeni is niet volledig in het Nederlands*. Sommige onderdelen worden wel in een
6
6
 andere taal weergegeven dan Engels, maar deze zijn vaak automatisch via het
7
7
 Django-framework vertaald (zoals de namen van dagen). Hier dient wel
8
8
 genuanceerd te worden dat Blackboard eveneens niet in het Nederlands is. Voor
9
9
 Joeni was meertalig zijn geen prioriteit, en dus is er meer aandacht besteedt
10
10
 aan het maken van een volledig /functioneel/ programma, dan een volledig
11
11
 /vertaald/ programma. Moest Joeni echter later ook ingezet worden binnen de
12
12
 UHasselt, dan is vertalen in Nederlands, Frans, Duits, ... uiterst simpel: Alle
13
13
 infrastructuur om te vertalen is al aanwezig in het Django-framework zelf. In
14
14
 de code zijn alle te vertalen blokken ook gemarkeerd.
15
15
**** Missende pagina's
16
16
Niet alle pagina's zitten in Joeni en het is zeker niet mogelijk om direct Bb.
17
17
en Std. te vervangen. Er is hier ook een afweging gemaakt tussen complexiteit en
18
18
functionaliteit.\\
19
19
Tijdens het schrijven van Joeni werd snel duidelijk dat veel functionaliteit van
20
20
Std. verouderd is, en het herimplementeren zou dus nooit nodig zijn. Een goed
21
21
voorbeeld hiervan is de link naar het JOS-project van de VDAB[fn:jobteaser]: De link die op
22
22
het Std. te vinden is, wordt nu automatisch doorverwezen naar de hoofdpagina van
23
23
de VDAB. Sommige attesten op Std. worden ook uitgegeven door bepaalde diensten,
24
24
en daarvan kan natuurlijk niet op voorhand geweten zijn welke attesten.
25
25
26
26
Sommige pagina's konden gewoonweg niet gereproduceerd worden, omdat ze links
27
27
genereren naar bepaalde PDF-bestanden.
28
28
29
29
[fn:jobteaser] Op dit moment blijken de links naar het JOS-project offline
30
30
gehaald te zijn, en vervangen door een ander systeem genaamd "Jobteaser", maar
31
31
het is maar de vraag hoe lang deze links blijven staan.
32
32
*** Uurrooster
33
33
Het uurrooster biedt *geen mogelijkheid om planning van andere richtingen in te kijken*.
34
34
Ik vermoed niet dat dit iets is wat veel mensen zullen missen, maar dit
35
35
kan wel later worden toegevoegd als dit nodig blijkt te zijn. Joeni heeft dit
36
36
niet omdat het de bedoeling was om een zo simpel mogelijk systeem te ontwerpen
37
37
dat zoveel mogelijk mensen tegemoet komt. De mogelijkheid om planningen in te
38
38
kijken van andere studierichtingen is niet nuttig genoeg om te toevoeging ervan
39
39
te verantwoorden.
40
40
41
41
De *vorm van de weergave van de week* was een kritiekpunt op zich van een van de
42
42
testers; die merkte op dat de breedte van de verschillende dagen niet gelijk is.
43
43
Dit klopt ook: Dagen zonder "evenementen" worden dunner weergegeven dan dagen
44
44
waarop wel iets gebeurt. De argumentering hiervan is tweeledig: Enerzijds is het
45
45
logisch om belangrijkere zaken (een bezette dag) prominenter weer te geven dan
46
46
onbelange zaken (een vrije dag), en dat wordt bekomen door ze breder te maken.
47
47
Anderzijds vereist elke dag even breed maken extra opmaakcode.\\
48
48
49
49
*** Lokalen
+
50
*kwartieren*. Dat betekent dat bv. een hoorcollege moet beginnen én eindigen op
+
51
##:00, ##:15, ##:30 of ##:45.\\
+
52
Deze beperking is ingevoerd, omdat voor de HTML-tabel op voorhand bepaald moet
+
53
worden hoeveel rijen in de tabel zitten. Om te voorkomen dat er hier problemen
+
54
optreden (en dat er voor elke minuut een aparte rij gemaakt moet worden), is er
+
55
besloten om alles op te delen in kwartieren. Dit werkt voor haast alle gevallen.
+
56
Het alternatief maakt het geheel weer een stuk gecompliceerder, en zou maar
+
57
enkele randgevallen helpen. Het voordeel weegt niet op tegen de complexiteit.
+
58
+
59
*** Enkel gehele studiepunten
+
60
In de databank van Joeni staat aangegeven dat een vak enkel een
+
61
=PositiveSmallInteger= kan zijn. Concreet betekent dit dat studiepunten een
+
62
geheel getal moeten zijn in het bereik [0,32767], ruim voldoende om alle vakken
+
63
te kunnen beschrijven.
+
64
+
65
Ik ben er later echter achter gekomen dat het gemeenschappelijke bachelorjaar
+
66
voor de opleiding Handelsingenieur vakken heeft die 1,5 studiepunten tellen, en
+
67
dat kan niet als een geheel getal opgeslagen worden.
+
68
+
69
Hier toch ondersteuning voor implementeren brengt enkele problemen mee:
+
70
Niet alleen impliceert dit dat elk /record/ van de vakken 2 bytes extra nodig
+
71
heeft, bepaalde berekeningen (zoals het gebruikelijke aantal studie-uren) kunnen
+
72
hierdoor later problemen veroorzaken, omdat niet alle reële getallen met
+
73
/floating point/ uitgedrukt kunnen worden. Daarbovenop komt dat Joeni probeert
+
74
zo simpel mogelijk te zijn, en tegelijk zoveel mogelijk problemen kan oplossen.
+
75
Dit uiterste randgeval is het oplossen niet waard. Als het dat wel is, dan kan
+
76
dat in de toekomst nog worden aangepast. 
+
77
*** Lokalen
50
78
Dit moet grotendeels worden ingevuld met *recente* informatie over de lokalen op
51
79
de UHasselt. Volgens Ines Boonen is er geen systeem informatie bijhoudt over de
52
80
lokalen, het is dus zeer waarschijnlijk dat de bestaande informatie dan ook niet
53
81
meer up-to-date is. Dit is natuurlijk gemakkelijk te remediëren door een dag de
54
82
universiteit rond te trekken en alle informatie te verzamelen.
55
83
56
84
Dit is op dit moment nog niet gedaan voor Joeni, omdat dit geen prioriteit was
57
85
van het project. Er zijn enkele voorbeeldlokalen ingevoerd om te laten zien dat
58
86
het systeem goed werkt en bruikbare informatie verschaft, maar langs alle
59
87
lokalen van de UHasselt gaan behoort niet tot de /scope/ van dit proefwerk.
60
88
61
89
*** Prikbord
62
90
Niet alle diensten die op het prikbord iets kunnen zetten, kunnen aangeven wie
63
91
een bepaald bericht kan zien. Tot nu toe kan enkel de examencommissie bepalen
64
92
wie een bericht mag zien, omdat de meeste van hun berichten toch gericht zijn
65
93
aan een enkele student.\\
66
94
Dit is nog niet geïmplementeerd omdat nog niet zeker is wat de meest
67
95
waarschijnlijke manier is dat informatie gedeeld wordt door de verschillende
68
96
diensten. Vermoedelijk zijn de meeste berichten toch bedoeld voor alle studenten
69
97
(getuige de PDF's die studeerruimte aanbieden), maar het kan natuurlijk dat
70
98
sommige berichten enkel aan een bepaalde studierichting getoond moeten worden.
71
99
72
100
*** Geen inschrijvingspagina
73
101
Nieuwe studenten kunnen zich via de website voorinschrijven op de UHasselt.
74
102
Alhoewel dit mooi geïntegreerd zou kunnen worden in Joeni, is er toch beslist
75
103
dit niet te doen.[fn:prereg-table]
76
104
77
105
Ten eerste is dit niet echt per sé nodig: Ook al vereist de voorinschrijving het
78
106
gebruik van /client side scripting/, het is niet zo doorgedreven als bij andere
79
107
onderdelen van de website. Daarnaast de pagina er esthetisch gezien nog goed
80
108
genoeg uit.\\
81
109
Ten tweede: Dit is een pagina waar haast alle studenten maar één keer in hun
82
110
hele leven mee in contact zullen komen. Om hiervoor een pagina toe te voegen aan
83
111
Joeni is nogal overbodig, er zijn namelijk tal van andere mogelijke
84
112
verbeteringen die veel vaker gebruikt zullen worden.
85
113
*** Agora?
86
114
Het originele project was groter dan wat Joeni op dit moment is; het eerste
87
115
voorstel omvatte ook een universitair communicatieplatform waarop studenten,
88
116
docenten en vakgroepen makkelijk met elkaar konden communiceren. Naast
89
117
Administratie en Vakken zou dit onderdeel Agora noemen.\\
90
118
Maar Agora staat in het menu doorgekrast. Uiteindelijk zit het niet in Joeni,
91
119
voornamelijk omwille van de grootte van het project, maar ook omdat het niet
92
120
direct tot een basistaak van de universiteit behoort. 
93
121
94
122
De tabellen die Agora mogelijk maken zijn echter a
95
123
96
124
[fn:prereg-table] voor volledigheid van de databank is er wel een tabel
97
125
aangemaakt waarin de voorinschrijvingen kunnen worden opgeslagen, ~~PreRegistration~~.

joeni/settings.py

1 addition and 1 deletion.

View changes Hide changes
1
1
Django settings for Joeni project.
2
2
3
3
Generated by 'django-admin startproject' using Django 2.0b1.
4
4
5
5
For more information on this file, see
6
6
https://docs.djangoproject.com/en/dev/topics/settings/
7
7
8
8
For the full list of settings and their values, see
9
9
https://docs.djangoproject.com/en/dev/ref/settings/
10
10
"""
11
11
12
12
import os
13
13
14
14
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
15
15
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16
16
17
17
18
18
# Quick-start development settings - unsuitable for production
19
19
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
20
20
21
21
# SECURITY WARNING: keep the secret key used in production secret!
22
22
SECRET_KEY = '!2634qc=b*lp0=helzcmvb3+1_wcl!6z@mhzi%p(vg7odq&gfz'
23
23
# TEMP Password: adminadmin | admin
24
24
25
25
# SECURITY WARNING: don't run with debug turned on in production!
26
26
DEBUG = True
27
27
28
28
ALLOWED_HOSTS = []
29
29
30
30
31
31
# Application definition
32
32
33
33
INSTALLED_APPS = [
34
34
    'django.contrib.admin',
35
35
    'django.contrib.auth',
36
36
    'django.contrib.contenttypes',
37
37
    'django.contrib.humanize',
38
38
    'django.contrib.sessions',
39
39
    'django.contrib.messages',
40
40
    'django.contrib.staticfiles',
41
41
    'administration',
42
42
    'agora',
43
43
    'courses',
44
44
    'joeni',
45
45
]
46
46
47
47
MIDDLEWARE = [
48
48
    'django.middleware.security.SecurityMiddleware',
49
49
    'django.middleware.locale.LocaleMiddleware',
50
50
    'django.middleware.common.CommonMiddleware',
51
51
    'django.middleware.csrf.CsrfViewMiddleware',
52
52
    'django.contrib.sessions.middleware.SessionMiddleware',
53
53
    'django.contrib.auth.middleware.AuthenticationMiddleware',
54
54
    'django.contrib.sessions.middleware.SessionMiddleware',
55
55
    'django.contrib.messages.middleware.MessageMiddleware',
56
56
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
57
57
    'django.middleware.security.SecurityMiddleware',
58
58
    # Caching middleware
59
59
    'django.middleware.cache.UpdateCacheMiddleware',
60
60
    'django.middleware.common.CommonMiddleware',
61
61
    'django.middleware.cache.FetchFromCacheMiddleware',
62
62
]
63
63
64
64
# Caching settings
65
65
CACHE_MIDDLEWARE_ALIAS = 'default'
66
66
CACHE_MIDDLEWARE_SECONDS = 300
67
67
CACHE_MIDDLEWARE_KEY_PREFIX = ''
68
68
69
69
ROOT_URLCONF = 'joeni.urls'
70
70
71
71
TEMPLATES = [
72
72
    {
73
73
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
74
74
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
75
75
        'APP_DIRS': True,
76
76
        'OPTIONS': {
77
77
            'context_processors': [
78
78
                'django.template.context_processors.debug',
79
79
                'django.template.context_processors.request',
80
80
                'django.contrib.auth.context_processors.auth',
81
81
                'django.contrib.messages.context_processors.messages',
82
82
            ],
83
83
        },
84
84
    },
85
85
]
86
86
87
87
#WSGI_APPLICATION = 'joeni.wsgi.application'
88
88
89
89
90
90
# Database
91
91
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
92
92
93
93
DATABASES = {
94
94
    'default': {
95
95
        'ENGINE': 'django.db.backends.sqlite3',
96
96
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
97
97
    }
98
98
}
99
99
100
100
# Page to display when a user needs / wants to log in
101
101
LOGIN_URL = '/login'
102
102
103
103
# Custom User model
104
104
AUTH_USER_MODEL = 'administration.User'
105
105
106
106
# Password validation
107
107
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
108
108
109
109
AUTH_PASSWORD_VALIDATORS = []
110
110
if not DEBUG:
111
111
    # XXX: For testing and easily creating new accounts, I've disabled the
112
112
    # validators to make it easier to work with.
113
113
    AUTH_PASSWORD_VALIDATORS = [
114
114
        {
115
115
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
116
116
        },
117
117
        {
118
118
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
119
119
        },
120
120
        {
121
121
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
122
122
        },
123
123
        {
124
124
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
125
125
        },
126
126
    ]
127
127
128
128
CACHES = {
129
129
    'default': {
130
130
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
131
131
    }
132
132
}
133
133
134
134
# Internationalization
135
135
# https://docs.djangoproject.com/en/dev/topics/i18n/
136
136
137
137
LANGUAGE_CODE = 'en-us'
138
138
139
139
TIME_ZONE = 'UTC'
140
-
+
140
141
141
USE_I18N = True
142
142
143
143
USE_L10N = True
144
144
145
145
USE_TZ = True
146
146
147
147
148
148
# Static files (CSS, JavaScript, Images)
149
149
# https://docs.djangoproject.com/en/dev/howto/static-files/
150
150
151
151
STATICFILES_DIRS = [
152
152
    BASE_DIR + "/static",
153
153
    ]
154
154
#STATIC_ROOT = BASE_DIR + '/static/'
155
155
STATIC_URL = '/static/'
156
156
MEDIA_URL = '/media/'
157
157

joeni/templates/joeni/header.djhtml

1 addition and 0 deletions.

View changes Hide changes
1
1
{% load static %}
2
2
{% get_media_prefix as media %}
3
3
<img src="{% static "logos/uhasselt/simple_white.svg" %}" alt="◀ Joeni /▶" />
4
4
<nav>
5
5
    <ul>
6
6
        <!--<li><a href="{% url 'agora-index' %}">Agora</a>-->
7
7
        <li><del>Agora</del></li>
8
8
            <ul>
9
9
            </ul>
10
10
        </li>
11
11
12
12
        <li><a href="{% url 'administration-index' %}">{% trans "Administration" %}</a>
13
13
            <ul>
14
14
                <li><a href="{% url 'administration-settings' %}">{% trans "Personal settings" %}</a></li>
15
15
                <li><a href="{% url 'administration-curriculum' %}">{% trans "Curricula" %}</a></li>
16
16
                <li><a href="{% url 'administration-forms' %}">{% trans "Forms" %}</a></li>
+
17
                <li><a href="{% url 'administration-forms' %}">{% trans "Forms" %}</a></li>
17
18
                <li><a href="{% url 'administration-rooms' %}">{% trans "Rooms" %}</a></li>
18
19
                <li><a href="{% url 'administration-jobs' %}">{% trans "Jobs" %}</a></li>
19
20
                <li><a href="{% url 'administration-roster' %}">{% trans "Personal Roster" %}</a></li>
20
21
                <li><a href="{% url 'administration-bulletin-board' %}">{% trans "Bulletin board" %}</a></li>
21
22
            </ul>
22
23
        </li>
23
24
24
25
        <li><a href="{% url 'courses-index' %}">{% trans "Courses" %}</a>
25
26
            <ul>
26
27
                {% for course in user.user_data.current_courses %}
27
28
                    <li><a href="{% url 'courses-course-index' course.slug_name %}">{{ course.name }}</a></li>
28
29
                {% endfor %}
29
30
            </ul>
30
31
        </li>
31
32
    </ul>
32
33
</nav>
33
34
{# PingPing: €{{ money }} #}
34
35

static/css/global.scss

1 addition and 1 deletion.

View changes Hide changes
1
1
    font-family: Verdana, Futura, Arial, sans-serif;
2
2
    margin: 0 0 0 0;
3
3
    height: 100%;
4
4
}
5
5
6
6
time {
7
-
    font-size: small;
+
7
    font-size: small;
8
8
    color: grey;
9
9
}
10
10

static/css/stylesheet.scss

1 addition and 0 deletions.

View changes Hide changes
1
1
by using sassc, put in one single file, stylesheet.css. However, that may not be
2
2
what you want when using HTTP/2. In that case, edit the scripts and templates
3
3
accordingly. */
4
4
@import 'variables';
5
5
@import 'classes.scss';
6
6
@import 'global.scss';
7
7
@import 'main.scss';
+
8
@import 'main.scss';
8
9
@import 'header.scss';
9
10
@import 'footer.scss';
10
11
@import 'base.scss'; // TODO: Rename to something proper
11
12

static/css/tables.scss

31 additions and 0 deletions.

View changes Hide changes
+
1
    /*border-width: 0.5em;
+
2
    border-style: solid;
+
3
    border-radius: 1em;
+
4
    padding: 0.8em;
+
5
    margin: 1em;*/
+
6
    border-width: 0.4em;
+
7
    border-style: solid;
+
8
    border-radius: 0.4em 1em 1em 1em;
+
9
    padding: 0;
+
10
    padding-left: 1em;
+
11
    color: inherit;
+
12
    padding-top: 0.5em;
+
13
    &:hover {
+
14
        text-decoration: none;
+
15
    }
+
16
    span.number {
+
17
        color: white;
+
18
        padding: 0.5em;
+
19
        margin-left: -1em;
+
20
        top: -1em;
+
21
        font-weight: bold;
+
22
        border-bottom-right-radius: 1em;
+
23
    }
+
24
    div.timetable-under {
+
25
        padding-left: 0.5em;
+
26
        margin-top: 0.5em;
+
27
        margin-bottom: 0.3em;
+
28
        margin-left: -1em;
+
29
    }
+
30
}
+
31