Add base joeni app files and .gitignore
- Author
- Maarten 'Vngngdn' Vangeneugden
- Date
- Nov. 14, 2017, 8:49 p.m.
- Hash
- 1e65844b20cb230538a004c3c1229bca1df5eea4
- Parent
- 697d3594d74c3d7a19ad27b7f54e4b7a794c2176
- Modified files
- .gitignore
- joeni/constants.py
- joeni/models.py
- joeni/templates/joeni/footer.html
.gitignore ¶
10 additions and 0 deletions.
joeni/constants.py ¶
17 additions and 0 deletions.
View changes Hide changes
+ |
1 |
If there is a discrepancy about a certain constant, this file is the definite |
+ |
2 |
point of reference. |
+ |
3 |
""" |
+ |
4 |
|
+ |
5 |
from django.utils.translation import ugettext_lazy as _ |
+ |
6 |
|
+ |
7 |
COLORS = { |
+ |
8 |
_("UHasselt default"): "E73B2B", |
+ |
9 |
_("Faculty of Sciences"): "0076BE", |
+ |
10 |
_("Faculty of Transportation Sciences"): "C0D633", |
+ |
11 |
_("Faculty of Architecture and Arts"): "F4802D", |
+ |
12 |
_("Faculty of Business Economics"): "00ACEE", |
+ |
13 |
_("Faculty of Medicine and Life Sciences"): "9C3591", |
+ |
14 |
_("Faculty of Engineering Technology"): "5BC4BA", |
+ |
15 |
_("Faculty of Law"): "E41F3A", |
+ |
16 |
} |
+ |
17 |
joeni/models.py ¶
210 additions and 0 deletions.
View changes Hide changes
+ |
1 |
from django.core.exceptions import ValidationError # For validating IBAN input |
+ |
2 |
from django.utils.translation import ugettext_lazy as _ |
+ |
3 |
from django.db import models |
+ |
4 |
import datetime |
+ |
5 |
import os |
+ |
6 |
|
+ |
7 |
class room(models.Model): |
+ |
8 |
""" Represents a room in the university. |
+ |
9 |
Rooms can have a number of properties, which are stored in the database. |
+ |
10 |
""" |
+ |
11 |
name = models.TextField() |
+ |
12 |
seats = models.IntegerField() |
+ |
13 |
wheelchair_accessible = models.BooleanField(default=True,blank=False) |
+ |
14 |
exams_equipped = models.BooleanField(blank=False) |
+ |
15 |
|
+ |
16 |
class User(models.Model): |
+ |
17 |
""" Replacement for the standard Django User model. """ |
+ |
18 |
number = models.PositiveIntegerField( |
+ |
19 |
primary_key=True, |
+ |
20 |
help_text=_("The number assigned to this user."), |
+ |
21 |
) |
+ |
22 |
created = models.DateField(auto_now_add=True) |
+ |
23 |
passphrase = models.CharField( |
+ |
24 |
max_length=512, |
+ |
25 |
blank=False, |
+ |
26 |
help_text=_("The passphrase used for this account. This field must only contain hashed information."), |
+ |
27 |
) |
+ |
28 |
first_name = models.CharField(max_length=64, blank=False) |
+ |
29 |
last_name = models.CharField(max_length=64, blank=False) |
+ |
30 |
DOB = models.DateField( |
+ |
31 |
blank=False, |
+ |
32 |
editable=False, |
+ |
33 |
help_text=_("The date of birth of this user."), |
+ |
34 |
) |
+ |
35 |
POB = models.CharField( |
+ |
36 |
max_length=64, |
+ |
37 |
blank=False, |
+ |
38 |
editable=False, |
+ |
39 |
help_text=_("The place of birth of this user."), |
+ |
40 |
) |
+ |
41 |
nationality = models.CharField( |
+ |
42 |
max_length=64, |
+ |
43 |
blank=False, |
+ |
44 |
help_text=_("The current nationality of this user."), |
+ |
45 |
) |
+ |
46 |
national_registry_number = models.BigIntegerField( |
+ |
47 |
unique=True, |
+ |
48 |
editable=False, |
+ |
49 |
help_text=_("The assigned national registry number of this user."), |
+ |
50 |
) |
+ |
51 |
civil_status = models.CharField( |
+ |
52 |
choices = ( |
+ |
53 |
("Single", _("Single")), |
+ |
54 |
("Married", _("Married")), |
+ |
55 |
("Divorced", _("Divorced")), |
+ |
56 |
("Widowed", _("Widowed")), |
+ |
57 |
("Partnership", _("Partnership")), |
+ |
58 |
), |
+ |
59 |
blank=False, |
+ |
60 |
# There may be more; consult http://www.aantrekkingskracht.com/trefwoord/burgerlijke-staat |
+ |
61 |
# for more information. |
+ |
62 |
help_text=_("The civil/marital status of the user."), |
+ |
63 |
) |
+ |
64 |
|
+ |
65 |
# Home address |
+ |
66 |
home_street = models.CharField(max_length=64, blank=False) |
+ |
67 |
home_number = models.PositiveSmallIntegerField(blank=False) |
+ |
68 |
home_bus = models.PositiveSmallIntegerField() |
+ |
69 |
home_postal_code = models.PositiveSmallIntegerField(blank=False) |
+ |
70 |
home_country = models.CharField(max_length=64, blank=False) |
+ |
71 |
home_telephone = models.CharField( |
+ |
72 |
max_length=64, |
+ |
73 |
help_text=_("The telephone number for the house address. Prefix 0 can be presented with the national call code in the system."), |
+ |
74 |
) |
+ |
75 |
# Study address |
+ |
76 |
study_street = models.CharField(max_length=64, blank=False) |
+ |
77 |
study_number = models.PositiveSmallIntegerField(blank=False) |
+ |
78 |
study_bus = models.PositiveSmallIntegerField() |
+ |
79 |
study_postal_code = models.PositiveSmallIntegerField(blank=False) |
+ |
80 |
study_country = models.CharField(max_length=64, blank=False) |
+ |
81 |
study_telephone = models.CharField( |
+ |
82 |
max_length=64, |
+ |
83 |
help_text=_("The telephone number for the study address. Prefix 0 can be presented with the national call code in the system."), |
+ |
84 |
) |
+ |
85 |
study_cellphone = models.CharField( |
+ |
86 |
max_length=64, |
+ |
87 |
help_text=_("The cellphone number of the person. Prefix 0 can be presented with then national call code in the system."), |
+ |
88 |
) |
+ |
89 |
# Titularis address |
+ |
90 |
# XXX: These fields are only required if this differs from the user itself. |
+ |
91 |
titularis_street = models.CharField(max_length=64) |
+ |
92 |
titularis_number = models.PositiveSmallIntegerField() |
+ |
93 |
titularis_bus = models.PositiveSmallIntegerField() |
+ |
94 |
titularis_postal_code = models.PositiveSmallIntegerField() |
+ |
95 |
titularis_country = models.CharField(max_length=64) |
+ |
96 |
titularis_telephone = models.CharField( |
+ |
97 |
max_length=64, |
+ |
98 |
help_text=_("The telephone number of the titularis. Prefix 0 can be presented with the national call code in the system."), |
+ |
99 |
) |
+ |
100 |
|
+ |
101 |
# Financial details |
+ |
102 |
bank_account_number = models.CharField( |
+ |
103 |
max_length=34, # Max length of all IBAN account numbers |
+ |
104 |
validators=[validate_IBAN], |
+ |
105 |
help_text=_("The IBAN of this user. No spaces!"), |
+ |
106 |
) |
+ |
107 |
BIC = models.CharField( |
+ |
108 |
max_length=11, |
+ |
109 |
validators=[validate_BIC], |
+ |
110 |
help_text=_("The BIC of this user's bank."), |
+ |
111 |
) |
+ |
112 |
|
+ |
113 |
def validate_IBAN(value): |
+ |
114 |
""" Validates if the given value qualifies as a valid IBAN number. |
+ |
115 |
This validator checks if the structure is valid, and calculates the control |
+ |
116 |
number if the structure is correct. If the control number fails, or the |
+ |
117 |
structure is invalid, a ValidationError will be raised. In that case, |
+ |
118 |
the Error will specify whether the structure is incorrect, or the control |
+ |
119 |
number is not valid. |
+ |
120 |
""" |
+ |
121 |
# FIXME: This function is not complete. When there's time, implement |
+ |
122 |
# as specified at https://nl.wikipedia.org/wiki/International_Bank_Account_Number#Structuur |
+ |
123 |
if False: |
+ |
124 |
raise ValidationError( |
+ |
125 |
_('%(value)s is not a valid IBAN number.'), |
+ |
126 |
params={'value': value},) |
+ |
127 |
def validate_BIC(value): |
+ |
128 |
""" Same functionality as validate_IBAN, but for BIC-codes. """ |
+ |
129 |
# FIXME: This function is not complete. When there's time, implement |
+ |
130 |
# as specified at https://nl.wikipedia.org/wiki/Business_Identifier_Code |
+ |
131 |
pass |
+ |
132 |
|
+ |
133 |
|
+ |
134 |
""" NOTE: What about all the other features that should be in the administration? |
+ |
135 |
While there are a lot of things to cover, as of now, I have no way to know which |
+ |
136 |
ones are still valid, which are deprecated, and so on... |
+ |
137 |
Additionally, every feature may have a different set of requirements, data, |
+ |
138 |
and it's very likely making an abstract class won't do any good. Thus I have |
+ |
139 |
decided to postpone making additional tables and forms for these features until |
+ |
140 |
I have clearance about certain aspects. """ |
+ |
141 |
|
+ |
142 |
def post_title_directory(instance, filename): |
+ |
143 |
""" Files will be uploaded to MEDIA_ROOT/blog/<year of publishing>/<blog |
+ |
144 |
title> |
+ |
145 |
The blog title is determined by the text before the first period (".") in |
+ |
146 |
the filename. So if the file has the name "Trains are bæ.en.md", the file |
+ |
147 |
will be stored in "blog/<this year>/Trains are bæ". Name your files |
+ |
148 |
properly! |
+ |
149 |
It should also be noted that all files are stored in the same folder if they |
+ |
150 |
belong to the same blogpost, regardless of language. The titles that are |
+ |
151 |
displayed to the user however, should be the titles of the files themselves, |
+ |
152 |
which should be in the native language. So if a blog post is titled |
+ |
153 |
"Universities of Belgium", its Dutch counterpart should be titled |
+ |
154 |
"Universiteiten van België", so the correct title can be derived from the |
+ |
155 |
filename. |
+ |
156 |
|
+ |
157 |
Recommended way to name the uploaded file: "<name of blog post in language |
+ |
158 |
it's written>.md". This removes the maximum amount of redundancy (e.g. the |
+ |
159 |
language of the file can be derived from the title, no ".fr.md" or something |
+ |
160 |
like that necessary), and can directly be used for the end user (the title |
+ |
161 |
is what should be displayed). |
+ |
162 |
""" |
+ |
163 |
english_file_name = os.path.basename(instance.english_file.name) # TODO: Test if this returns the file name! |
+ |
164 |
english_title = english_file_name.rpartition(".")[0] |
+ |
165 |
year = datetime.date.today().year |
+ |
166 |
|
+ |
167 |
return "blog/{0}/{1}/{2}".format(year, english_title, filename) |
+ |
168 |
|
+ |
169 |
class Post(models.Model): |
+ |
170 |
""" Represents a blog post. The title of the blog post is determnined by the name |
+ |
171 |
of the files. |
+ |
172 |
A blog post can be in 5 different languages: German, Spanish, English, French, |
+ |
173 |
and Dutch. For all these languages, a seperate field exists. Thus, a |
+ |
174 |
translated blog post has a seperate file for each translation, and is |
+ |
175 |
seperated from Django's internationalization/localization system. |
+ |
176 |
Only the English field is mandatory. The others may contain a value if a |
+ |
177 |
translated version exists, which will be displayed accordingly. |
+ |
178 |
""" |
+ |
179 |
published = models.DateTimeField(auto_now_add=True) |
+ |
180 |
english_file = models.FileField(upload_to=post_title_directory, unique=True, blank=False) |
+ |
181 |
dutch_file = models.FileField(upload_to=post_title_directory, blank=True) |
+ |
182 |
french_file = models.FileField(upload_to=post_title_directory, blank=True) |
+ |
183 |
german_file = models.FileField(upload_to=post_title_directory, blank=True) |
+ |
184 |
spanish_file = models.FileField(upload_to=post_title_directory, blank=True) |
+ |
185 |
# Only the English file can be unique, because apparantly, there can't be |
+ |
186 |
# two blank fields in a unique column. Okay then. |
+ |
187 |
|
+ |
188 |
def __str__(self): |
+ |
189 |
return os.path.basename(self.english_file.name).rpartition(".")[0] |
+ |
190 |
|
+ |
191 |
#class Comment(models.model): |
+ |
192 |
""" Represents a comment on a blog post. |
+ |
193 |
|
+ |
194 |
Comments are not linked to an account or anything, I'm trusting the |
+ |
195 |
commenter that he is honest with his credentials. That being said: |
+ |
196 |
XXX: Remember to put up a notification that comments are not checked for |
+ |
197 |
identity, and, unless verified by a trustworthy source, cannot be seen as |
+ |
198 |
being an actual statement from the commenter. |
+ |
199 |
Comments are linked to a blogpost, and are not filtered by language. (So a |
+ |
200 |
comment made by someone reading the article in Dutch, that's written in |
+ |
201 |
Dutch, will show up (unedited) for somebody whom's reading the Spanish |
+ |
202 |
version. |
+ |
203 |
XXX: Remember to notify (tiny footnote or something) that comments showing |
+ |
204 |
up in a foreign language is by design, and not a bug. |
+ |
205 |
""" |
+ |
206 |
# date = models.DateTimeField(auto_now_add=True) |
+ |
207 |
#name = models.TextField() |
+ |
208 |
#mail = models.EmailField() |
+ |
209 |
#post = models.ForeignKey(Post) # TODO: Finish this class and the shit... |
+ |
210 |
joeni/templates/joeni/footer.html ¶
3 additions and 0 deletions.