Python3 compatibility
[vagrant-mail.git] / database / platal / models.py
1 # -*- coding: utf-8 -*-
2 #***************************************************************************
3 #* Copyright (C) 2015 Polytechnique.org *
4 #* http://opensource.polytechnique.org/ *
5 #* *
6 #* This program is free software; you can redistribute it and/or modify *
7 #* it under the terms of the GNU General Public License as published by *
8 #* the Free Software Foundation; either version 2 of the License, or *
9 #* (at your option) any later version. *
10 #* *
11 #* This program is distributed in the hope that it will be useful, *
12 #* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 #* GNU General Public License for more details. *
15 #* *
16 #* You should have received a copy of the GNU General Public License *
17 #* along with this program; if not, write to the Free Software *
18 #* Foundation, Inc., *
19 #* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 #***************************************************************************/
21 """Django models which fit the latest version of Plat/al database
22
23 Latest version synced: Plat/al 1.1.15
24 https://github.com/Polytechnique-org/platal/tree/xorg/maint/upgrade
25
26 This requires Django to work.
27 """
28 from __future__ import unicode_literals
29 import collections
30 from django.db import models
31 from django.utils.encoding import python_2_unicode_compatible
32
33
34 def is_ax_visible(field):
35 return field in ('public', 'ax')
36
37
38 # Misc for Account/Profile
39 # ========================
40
41
42 @python_2_unicode_compatible
43 class Skin(models.Model):
44 #id = models.IntegerField(primary_key=True)
45 name = models.CharField(max_length=96)
46 date = models.DateField()
47 comment = models.CharField(max_length=765)
48 auteur = models.CharField(max_length=90)
49 skin_tpl = models.CharField(max_length=96)
50 ext = models.CharField(max_length=9)
51 class Meta:
52 db_table = 'skins'
53
54 def __str__(self):
55 return self.name
56
57
58 @python_2_unicode_compatible
59 class EmailVirtualDomain(models.Model):
60 #id = models.IntegerField(primary_key=True)
61 name = models.CharField(max_length=765)
62 aliasing = models.ForeignKey('self', db_column='aliasing')
63 class Meta:
64 db_table = 'email_virtual_domains'
65
66 def __str__(self):
67 return self.name
68
69
70 @python_2_unicode_compatible
71 class ProfileSectionEnum(models.Model):
72 #id = models.IntegerField(primary_key=True)
73 text = models.CharField(max_length=150, unique=True)
74 class Meta:
75 db_table = 'profile_section_enum'
76
77 def __str__(self):
78 return self.text
79
80
81 @python_2_unicode_compatible
82 class GeolocCountry(models.Model):
83 iso_3166_1_a2 = models.CharField(max_length=6, primary_key=True)
84 iso_3166_1_a3 = models.CharField(max_length=9, unique=True)
85 iso_3166_1_num = models.IntegerField(unique=True)
86 worldregion = models.CharField(max_length=6, db_column='worldRegion', blank=True) # Field name made lowercase.
87 country = models.CharField(max_length=765, blank=True)
88 countryen = models.CharField(max_length=765, db_column='countryEn', blank=True) # Field name made lowercase.
89 capital = models.CharField(max_length=765)
90 nationality = models.CharField(max_length=765, blank=True)
91 nationalityen = models.CharField(max_length=765, db_column='nationalityEn', blank=True) # Field name made lowercase.
92 phoneprefix = models.IntegerField(null=True, db_column='phonePrefix', blank=True) # Field name made lowercase.
93 phoneformat = models.CharField(max_length=765, db_column='phoneFormat') # Field name made lowercase.
94 licenseplate = models.CharField(max_length=12, db_column='licensePlate', blank=True) # Field name made lowercase.
95 belongsto = models.ForeignKey('self', null=True, db_column='belongsTo', blank=True) # Field name made lowercase.
96 countryplain = models.CharField(max_length=765, db_column='countryPlain', blank=True) # Field name made lowercase.
97 class Meta:
98 db_table = 'geoloc_countries'
99
100 def __str__(self):
101 return self.iso_3166_1_a2
102
103
104 # Account/Profile
105 # ===============
106
107
108 @python_2_unicode_compatible
109 class AccountType(models.Model):
110 type = models.CharField(max_length=48, primary_key=True)
111 perms = models.CharField(max_length=321)
112 description = models.TextField(blank=True)
113 class Meta:
114 db_table = 'account_types'
115
116 def __str__(self):
117 return self.type
118
119
120 @python_2_unicode_compatible
121 class Account(models.Model):
122 uid = models.AutoField(primary_key=True)
123 hruid = models.CharField(max_length=255, unique=True)
124 type = models.ForeignKey(AccountType, null=True, db_column='type', blank=True)
125 user_perms = models.CharField(max_length=288, blank=True)
126 is_admin = models.BooleanField()
127 state = models.CharField(max_length=24)
128 password = models.CharField(max_length=120, blank=True)
129 token = models.CharField(max_length=96, blank=True)
130 weak_password = models.CharField(max_length=768, blank=True)
131 registration_date = models.DateTimeField()
132 flags = models.CharField(max_length=15)
133 comment = models.CharField(max_length=765, blank=True)
134 email = models.CharField(max_length=765, blank=True)
135 firstname = models.CharField(max_length=765, blank=True)
136 lastname = models.CharField(max_length=765, blank=True)
137 full_name = models.CharField(max_length=765, blank=True)
138 directory_name = models.CharField(max_length=765, blank=True)
139 sort_name = models.CharField(max_length=765, blank=True)
140 display_name = models.CharField(max_length=765, blank=True)
141 sex = models.CharField(max_length=18)
142 email_format = models.CharField(max_length=12)
143 skin = models.ForeignKey(Skin, null=True, db_column='skin', blank=True)
144 last_version = models.CharField(max_length=48)
145 best_domain = models.ForeignKey(EmailVirtualDomain, null=True, db_column='best_domain', blank=True)
146 from_email = models.CharField(max_length=765)
147 from_format = models.CharField(max_length=12)
148 class Meta:
149 db_table = 'accounts'
150
151 def __str__(self):
152 return '%s (%s)' % (self.hruid, self.full_name)
153
154 @property
155 def profile(self):
156 return self.profiles.filter(perms='owner').get().profile
157
158
159 @python_2_unicode_compatible
160 class ProfileAlias(object):
161 def __init__(self, alias_of, kind, lastname, firstname=None):
162 self.alias_of = alias_of
163 self.kind = kind
164 self.lastname = lastname
165 self.firstname = alias_of.firstname if firstname is None else firstname
166
167 ALT_MARITAL = 'marital'
168 ALT_PSEUDO = 'pseudo'
169 ALT_ORDINARY = 'ordinary'
170
171 @property
172 def is_pseudo(self):
173 return self.kind == self.ALT_PSEUDO
174
175 def get_kind_display(self):
176 if self.kind == self.ALT_MARITAL:
177 if self.female:
178 return "Mme"
179 else:
180 return "M."
181 elif self.kind == self.ALT_PSEUDO:
182 return "Pseudonyme"
183 else:
184 return ""
185
186 def __getattr__(self, attr):
187 return getattr(self.alias_of, attr)
188
189 def __repr__(self):
190 return '<ProfileAlias %s of %r>' % (self.kind, self.alias_of)
191
192
193 @python_2_unicode_compatible
194 class Profile(models.Model):
195
196 alias_of = None
197
198 def __init__(self, *args, **kwargs):
199 super(Profile, self).__init__(*args, **kwargs)
200 self._aliases = None
201
202 pid = models.AutoField(primary_key=True)
203 hrpid = models.CharField(max_length=255, unique=True)
204 xorg_id = models.IntegerField()
205 ax_id = models.CharField(max_length=24, blank=True)
206 birthdate = models.DateField(null=True, blank=True)
207 birthdate_ref = models.DateField(null=True, blank=True)
208 next_birthday = models.DateField(null=True, blank=True)
209 deathdate = models.DateField(null=True, blank=True)
210 deathdate_rec = models.DateField(null=True, blank=True)
211 sex = models.CharField(max_length=18)
212 section = models.ForeignKey(ProfileSectionEnum, null=True, db_column='section', blank=True)
213 cv = models.TextField(blank=True)
214 freetext = models.TextField(blank=True)
215 freetext_pub = models.CharField(max_length=21)
216 medals_pub = models.CharField(max_length=21)
217 alias_pub = models.CharField(max_length=21)
218 nationality1 = models.ForeignKey(GeolocCountry, null=True, db_column='nationality1', blank=True, related_name='natives')
219 nationality2 = models.ForeignKey(GeolocCountry, null=True, db_column='nationality2', blank=True, related_name='second_natives')
220 nationality3 = models.ForeignKey(GeolocCountry, null=True, db_column='nationality3', blank=True, related_name='third_natives')
221 email_directory = models.CharField(max_length=765, blank=True)
222 last_change = models.DateField()
223 title = models.CharField(max_length=12)
224
225 class Meta:
226 db_table = 'profiles'
227
228 def __str__(self):
229 return self.hrpid
230
231 @property
232 def is_alive(self):
233 return self.deathdate is None
234
235 @property
236 def account(self):
237 return self.accounts.filter(perms='owner').get().account
238
239 @property
240 def firstname(self):
241 return self.public_name.firstname_ordinary or self.public_name.firstname_main or self.public_name.firstname_initial
242
243 @property
244 def lastname(self):
245 return self.public_name.lastname_main or self.public_name.lastname_initial
246
247 @property
248 def lastname_display(self):
249 return self.public_name.lastname_ordinary or self.public_name.lastname_marital or self.public_name.lastname_main or self.public_name.lastname_initial
250
251 @property
252 def lastname_marital(self):
253 return self.public_name.lastname_marital
254
255 @property
256 def lastname_ordinary(self):
257 return self.public_name.lastname_ordinary
258
259 @property
260 def pseudonym(self):
261 return self.public_name.pseudonym
262
263 @property
264 def promo(self):
265 return self.profiledisplay.promo
266
267 @property
268 def female(self):
269 return self.sex == 'female'
270
271 @property
272 def nationality(self):
273 return self.nationality1 or self.nationality2 or self.nationality3
274
275 @property
276 def country_code(self):
277 nat = self.nationality
278 if nat is None:
279 return 'FR'
280 return nat.iso_3166_1_a2
281
282 @property
283 def country_name(self):
284 nat = self.nationality
285 if nat is None:
286 return "France"
287 return nat.country
288
289 @property
290 def current_corps(self):
291 try:
292 return self.profilecorps.current
293 except ProfileCorps.DoesNotExist:
294 return None
295
296 def get_aliases(self, include_deviations=True):
297 if self._aliases is None:
298 self._aliases = []
299
300 alt_names = set([self.lastname])
301 if self.lastname_marital and self.lastname_marital not in alt_names:
302 alt_names.add(self.lastname_marital)
303 self._aliases.append(
304 ProfileAlias(self, ProfileAlias.ALT_MARITAL, self.lastname_marital))
305
306 if self.lastname_ordinary and self.lastname_ordinary not in alt_names:
307 # Some people filled 'ordinary' instead of 'marital'
308 alt_names.add(self.lastname_ordinary)
309 self._aliases.append(
310 ProfileAlias(self, ProfileAlias.ALT_ORDINARY, self.lastname_ordinary))
311
312 if self.pseudonym and self.pseudonym not in alt_names:
313 alt_names.add(self.pseudonym)
314 self._aliases.append(
315 ProfileAlias(self, ProfileAlias.ALT_PSEUDO, self.pseudonym, firstname=''))
316
317 if include_deviations:
318 return self._aliases
319 else:
320 return [a for a in self._aliases
321 if not a.lastname.startswith(self.lastname)
322 and not self.lastname.startswith(a.lastname)
323 ]
324
325 @property
326 def mobile_line(self):
327 if not hasattr(self, '_mobiles'):
328 mobiles = [phone
329 for phone in self.phones.all()
330 if phone.link_type == phone.LINK_USER and phone.tel_type == phone.KIND_MOBILE
331 ]
332 self._mobiles = sorted(mobiles, key=lambda p: p.tel_id)
333 if self._mobiles:
334 return self._mobiles[0]
335 return None
336
337 def sorted_addresses(self, for_ax=False):
338 personal_addresses = [addr
339 for addr in self.addresses.all()
340 if addr.is_home and (addr.ax_visible or not for_ax)
341 ]
342
343 address_phones = collections.defaultdict(lambda: collections.defaultdict(list))
344
345 for phone in self.phones.all():
346 if phone.is_address and (phone.ax_visible or not for_ax):
347 address_phones[phone.link_id][phone.tel_type].append(phone)
348
349 for address in personal_addresses:
350 addr_phones = {}
351 for kind, phones in address_phones[address.subid].items():
352 if phones:
353 addr_phones[kind] = sorted(phones, key=lambda p: p.tel_id)[0]
354 else:
355 addr_phones[kind] = None
356 address.phones = addr_phones
357
358 current = [addr for addr in personal_addresses if addr.current]
359 secondary = [addr for addr in personal_addresses if addr.secondary and not addr.current]
360 if not current:
361 current, secondary = secondary, []
362
363 return [(a, True) for a in current] + [(a, False) for a in secondary]
364
365 def sorted_educations(self):
366 edus = [edu for edu in self.educations.all() if edu.school and edu.school.abbreviation != 'X']
367 return sorted(edus, key=lambda edu: edu.entry_year)
368
369 def sorted_jobs(self):
370 jobs = sorted(self.jobs.all(), key=lambda j: (j.id, j.entry_year))
371 job_addresses = {}
372 for addr in self.addresses.all():
373 if addr.is_job:
374 job_addresses[addr.job_id] = addr
375
376 job_phones = collections.defaultdict(lambda: collections.defaultdict(list))
377 for phone in self.phones.all():
378 if phone.is_job:
379 job_phones[phone.link_id][phone.tel_type].append(phone)
380
381 for job in jobs:
382 job.address = job_addresses.get(job.id)
383 j_phones = {}
384 for kind, phones in job_phones[job.id].items():
385 if phones:
386 j_phones[kind] = sorted(phones, key=lambda p: p.tel_id)[0]
387 else:
388 j_phones[kind] = None
389 job.phones = j_phones
390
391 return jobs
392
393
394 @python_2_unicode_compatible
395 class AccountProfile(models.Model):
396 account = models.ForeignKey(Account, db_column='uid', related_name='profiles')
397 profile = models.ForeignKey(Profile, db_column='pid', related_name='accounts')
398 pkey = models.CompositeField(account, profile, primary_key=True)
399 perms = models.CharField(max_length=15)
400 class Meta:
401 db_table = 'account_profiles'
402
403 def __str__(self):
404 return '%s -> %s' % (self.account.hruid, self.profile.hrpid)
405
406
407 # Account-related
408 # ===============
409
410
411 @python_2_unicode_compatible
412 class AccountAuthOpenid(models.Model):
413 #id = models.IntegerField(primary_key=True)
414 account = models.ForeignKey(Account, unique=True, null=True, db_column='uid', blank=True)
415 url = models.CharField(max_length=255, unique=True)
416 class Meta:
417 db_table = 'account_auth_openid'
418
419 def __str__(self):
420 return "%s at %s" % (self.account, self.url)
421
422 @python_2_unicode_compatible
423 class AccountLostPassword(models.Model):
424 certificat = models.CharField(max_length=96, primary_key=True)
425 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
426 created = models.DateTimeField(null=True, blank=True)
427 class Meta:
428 db_table = 'account_lost_passwords'
429
430 def __str__(self):
431 return "%s on %s" % (self.account.hruid, self.created)
432
433
434 @python_2_unicode_compatible
435 class AccountXnetLostPassword(models.Model):
436 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
437 date = models.DateTimeField(null=True, blank=True)
438 hash = models.CharField(max_length=96)
439 class Meta:
440 db_table = 'account_xnet_lost_passwords'
441
442 def __str__(self):
443 return "%s on %s" % (self.account.hruid, self.date)
444
445
446 # Announces
447 # =========
448
449
450 @python_2_unicode_compatible
451 class Announce(models.Model):
452 #id = models.IntegerField(primary_key=True)
453 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
454 creation_date = models.DateTimeField()
455 titre = models.CharField(max_length=765)
456 texte = models.TextField()
457 expiration = models.DateField()
458 promo_min = models.IntegerField()
459 promo_max = models.IntegerField()
460 flags = models.CharField(max_length=87)
461 noinvite = models.IntegerField()
462 post_id = models.IntegerField(null=True, blank=True, editable=False,
463 help_text=u"NNTP post identifier")
464 class Meta:
465 db_table = 'announces'
466
467 def __str__(self):
468 return "%s: %s" % (self.id, self.titre)
469
470
471 @python_2_unicode_compatible
472 class AnnouncePhoto(models.Model):
473 eid = models.ForeignKey(Announce, primary_key=True, db_column='eid')
474 attachmime = models.CharField(max_length=12)
475 attach = models.TextField()
476 x = models.IntegerField()
477 y = models.IntegerField()
478 class Meta:
479 db_table = 'announce_photos'
480
481 def __str__(self):
482 return "%s (%s, %d x %d)" % (self.eid, self.attachmime, self.x, self.y)
483
484
485 @python_2_unicode_compatible
486 class AnnounceRead(models.Model):
487 evt = models.ForeignKey(Announce)
488 account = models.ForeignKey(Account, db_column='uid')
489 pkey = models.CompositeField(evt, account, primary_key=True)
490 class Meta:
491 db_table = 'announce_read'
492
493 def __str__(self):
494 return "%s: %s" % (self.account, self.evt)
495
496
497 # Email routing
498 # =============
499
500
501 @python_2_unicode_compatible
502 class EmailVirtual(models.Model):
503 email = models.CharField(max_length=255)
504 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
505 pkey = models.CompositeField(email, domain, primary_key=True)
506 redirect = models.CharField(max_length=765)
507 type = models.CharField(max_length=21, blank=True)
508 expire = models.DateField()
509 class Meta:
510 db_table = 'email_virtual'
511
512 def __str__(self):
513 return "%s@%s (%s)" % (self.email, self.domain, self.type)
514
515
516 @python_2_unicode_compatible
517 class EmailRedirectAccount(models.Model):
518 account = models.ForeignKey(Account, db_column='uid')
519 redirect = models.CharField(max_length=765)
520 pkey = models.CompositeField(account, redirect, primary_key=True)
521 rewrite = models.CharField(max_length=765)
522 type = models.CharField(max_length=30)
523 action = models.CharField(max_length=54)
524 broken_date = models.DateField()
525 broken_level = models.IntegerField()
526 last = models.DateField()
527 flags = models.CharField(max_length=24)
528 hash = models.CharField(max_length=96, blank=True)
529 allow_rewrite = models.BooleanField()
530 class Meta:
531 db_table = 'email_redirect_account'
532
533 def __str__(self):
534 return "%s for %s (%s)" % (self.redirect, self.account.hruid, self.type)
535
536
537 @python_2_unicode_compatible
538 class EmailSourceAccount(models.Model):
539 email = models.CharField(max_length=255)
540 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
541 pkey = models.CompositeField(email, domain, primary_key=True)
542
543 account = models.ForeignKey(Account, db_column='uid')
544 type = models.CharField(max_length=27)
545 flags = models.CharField(max_length=69)
546 expire = models.DateField(null=True, blank=True)
547 class Meta:
548 db_table = 'email_source_account'
549
550 def __str__(self):
551 return "%s@%s (%s)" % (self.email, self.domain, self.type)
552
553
554 @python_2_unicode_compatible
555 class EmailSourceOther(models.Model):
556 email = models.CharField(max_length=255)
557 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
558 pkey = models.CompositeField(email, domain, primary_key=True)
559
560 hrmid = models.CharField(max_length=765)
561 type = models.CharField(max_length=24, blank=True)
562 expire = models.DateField(null=True, blank=True)
563 class Meta:
564 db_table = 'email_source_other'
565
566 def __str__(self):
567 return "%s@%s (%s)" % (self.email, self.domain, self.type)
568
569
570 @python_2_unicode_compatible
571 class EmailRedirectOther(models.Model):
572 hrmid = models.ForeignKey(EmailSourceOther, db_column='hrmid')
573 redirect = models.CharField(max_length=765)
574 pkey = models.CompositeField(hrmid, redirect, primary_key=True)
575 type = models.CharField(max_length=30)
576 action = models.CharField(max_length=54)
577 class Meta:
578 db_table = 'email_redirect_other'
579
580 def __str__(self):
581 return "%s -> %s (%s)" % (self.hrmid, self.redirect, self.type)
582
583
584 # innd-related
585 # ============
586
587
588 @python_2_unicode_compatible
589 class InndForum(models.Model):
590 """ACLs for innd"""
591 id_innd = models.AutoField(primary_key=True)
592 ipmin = models.IntegerField(null=True, blank=True)
593 ipmax = models.IntegerField(null=True, blank=True)
594 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
595 read_perm = models.CharField(max_length=300, blank=True)
596 write_perm = models.CharField(max_length=300, blank=True)
597 priority = models.IntegerField(null=True, blank=True)
598 comment = models.TextField(blank=True)
599 class Meta:
600 db_table = 'forum_innd'
601
602 def __str__(self):
603 return "%d: %s" % (self.id_innd, self.account.hruid)
604
605
606 @python_2_unicode_compatible
607 class ForumProfile(models.Model):
608 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
609 name = models.CharField(max_length=192)
610 mail = models.CharField(max_length=210)
611 sig = models.TextField()
612 flags = models.CharField(max_length=63)
613 tree_unread = models.CharField(max_length=24)
614 tree_read = models.CharField(max_length=24)
615 last_seen = models.DateTimeField()
616 class Meta:
617 db_table = 'forum_profiles'
618
619 def __str__(self):
620 return "%s: %s" % (self.account.hruid, self.name)
621
622
623 @python_2_unicode_compatible
624 class Forum(models.Model):
625 fid = models.IntegerField(primary_key=True)
626 name = models.CharField(max_length=192)
627 class Meta:
628 db_table = 'forums'
629
630 def __str__(self):
631 return self.name
632
633
634 @python_2_unicode_compatible
635 class ForumSubs(models.Model):
636 forum = models.ForeignKey(Forum, db_column='fid')
637 account = models.ForeignKey(Account, db_column='uid')
638 pkey = models.CompositeField(forum, account, primary_key=True)
639 class Meta:
640 db_table = 'forum_subs'
641
642 def __str__(self):
643 return "%s by %s" % (self.forum.name, self.account.hruid)
644
645
646 # Payments
647 # ========
648
649
650 @python_2_unicode_compatible
651 class PaymentBankAccount(models.Model):
652 #id = models.IntegerField(primary_key=True)
653 asso = models.ForeignKey('Group', blank=True, null=True)
654 iban = models.CharField(max_length=33)
655 owner = models.CharField(max_length=300)
656 status = models.CharField(max_length=36)
657 bic = models.CharField(max_length=11)
658 class Meta:
659 db_table = 'payment_bankaccounts'
660
661 def __str__(self):
662 return '%s: %s' % (self.asso.name, self.account)
663
664
665 @python_2_unicode_compatible
666 class Payment(models.Model):
667 #id = models.IntegerField(primary_key=True)
668 text = models.CharField(max_length=765)
669 url = models.CharField(max_length=384)
670 flags = models.CharField(max_length=51)
671 amount_def = models.DecimalField(max_digits=12, decimal_places=2)
672 amount_min = models.DecimalField(max_digits=12, decimal_places=2)
673 amount_max = models.DecimalField(max_digits=12, decimal_places=2)
674 mail = models.CharField(max_length=192)
675 confirmation = models.TextField()
676 asso = models.ForeignKey('Group', null=True, blank=True)
677 rib = models.ForeignKey(PaymentBankAccount)
678 class Meta:
679 db_table = 'payments'
680
681 def __str__(self):
682 return "%s: %s" % (self.id, self.text)
683
684
685 @python_2_unicode_compatible
686 class PaymentCodeC(models.Model):
687 id = models.IntegerField(primary_key=True)
688 text = models.CharField(max_length=192)
689 class Meta:
690 db_table = 'payment_codeC'
691
692 def __str__(self):
693 return self.text
694
695
696 @python_2_unicode_compatible
697 class PaymentCodeRCB(models.Model):
698 id = models.IntegerField(primary_key=True)
699 text = models.CharField(max_length=192)
700 codec = models.IntegerField(db_column='codeC') # Field name made lowercase.
701 class Meta:
702 db_table = 'payment_codeRCB'
703
704 def __str__(self):
705 return self.text
706
707
708 @python_2_unicode_compatible
709 class PaymentMethod(models.Model):
710 id = models.IntegerField(primary_key=True)
711 text = models.CharField(max_length=96)
712 include = models.CharField(max_length=96)
713 short_name = models.CharField(max_length=30)
714 flags = models.CharField(max_length=36, blank=True)
715 class Meta:
716 db_table = 'payment_methods'
717
718 def __str__(self):
719 return self.short_name
720
721
722 @python_2_unicode_compatible
723 class PaymentReconcilation(models.Model):
724 #id = models.IntegerField(primary_key=True)
725 method = models.ForeignKey(PaymentMethod)
726 period_start = models.DateField()
727 period_end = models.DateField()
728 status = models.CharField(max_length=33)
729 payment_count = models.IntegerField()
730 sum_amounts = models.DecimalField(max_digits=11, decimal_places=2)
731 sum_commissions = models.DecimalField(max_digits=11, decimal_places=2)
732 comments = models.TextField()
733 recongroup_id = models.IntegerField(null=True, blank=True)
734 class Meta:
735 db_table = 'payment_reconcilations'
736
737 def __str__(self):
738 return "%s: %s" % (self.method, self.status)
739
740
741 @python_2_unicode_compatible
742 class PaymentTransaction(models.Model):
743 id = models.CharField(max_length=192, primary_key=True)
744 method = models.ForeignKey(PaymentMethod, null=True, blank=True)
745 account = models.ForeignKey(Account, db_column='uid')
746 ref = models.IntegerField()
747 fullref = models.CharField(max_length=45)
748 ts_confirmed = models.DateTimeField(null=True, blank=True)
749 ts_initiated = models.DateTimeField(null=True, blank=True)
750 amount = models.DecimalField(max_digits=11, decimal_places=2)
751 commission = models.DecimalField(null=True, max_digits=11, decimal_places=2, blank=True)
752 pkey = models.CharField(max_length=15)
753 comment = models.CharField(max_length=765)
754 status = models.CharField(max_length=27)
755 recon = models.ForeignKey(PaymentReconcilation, null=True, blank=True)
756 display = models.IntegerField()
757 class Meta:
758 db_table = 'payment_transactions'
759
760 def __str__(self):
761 return "%s (%s)" % (self.fullref, self.ref)
762
763
764 @python_2_unicode_compatible
765 class PaymentTransfer(models.Model):
766 #id = models.IntegerField(primary_key=True)
767 recongroup_id = models.IntegerField()
768 payment = models.ForeignKey(Payment)
769 amount = models.DecimalField(max_digits=11, decimal_places=2)
770 account = models.ForeignKey(Account, null=True, blank=True)
771 message = models.CharField(max_length=765)
772 date = models.DateField(null=True, blank=True)
773 class Meta:
774 db_table = 'payment_transfers'
775
776 def __str__(self):
777 return "%s: %s" % (self.id, self.amount)
778
779
780 # Groups
781 # ======
782
783
784 @python_2_unicode_compatible
785 class GroupDom(models.Model):
786 #id = models.IntegerField(primary_key=True)
787 name = models.TextField(db_column='nom')
788 cat = models.CharField(max_length=117)
789 class Meta:
790 db_table = 'group_dom'
791
792 def __str__(self):
793 return "%s :: %s" % (self.cat, self.name)
794
795
796 @python_2_unicode_compatible
797 class Group(models.Model):
798 #id = models.IntegerField(primary_key=True)
799 name = models.CharField(max_length=765, db_column='nom')
800 diminutif = models.CharField(max_length=192, unique=True)
801 cat = models.CharField(max_length=117)
802 dom = models.ForeignKey(GroupDom, null=True, db_column='dom', blank=True)
803 descr = models.TextField()
804 logo = models.TextField(blank=True)
805 logo_mime = models.TextField(blank=True)
806 site = models.CharField(max_length=765)
807 mail = models.CharField(max_length=765)
808 resp = models.CharField(max_length=765)
809 forum = models.CharField(max_length=765)
810 mail_domain = models.CharField(max_length=765)
811 ax = models.IntegerField()
812 pub = models.CharField(max_length=21)
813 sub_url = models.CharField(max_length=765)
814 inscriptible = models.IntegerField()
815 unsub_url = models.CharField(max_length=765)
816 flags = models.CharField(max_length=117)
817 axdate = models.DateField(null=True, db_column='axDate', blank=True) # Field name made lowercase.
818 welcome_msg = models.TextField(blank=True)
819 event_order = models.CharField(max_length=8)
820 disable_mails = models.BooleanField()
821 status = models.CharField(max_length=117)
822 class Meta:
823 db_table = 'groups'
824
825 def __str__(self):
826 return self.name
827
828
829 # Group::membership
830 # -----------------
831
832
833 @python_2_unicode_compatible
834 class GroupMember(models.Model):
835 asso = models.ForeignKey(Group)
836 account = models.ForeignKey(Account, db_column='uid')
837 pkey = models.CompositeField(asso, account, primary_key=True)
838
839 perms = models.CharField(max_length=18)
840 comm = models.CharField(max_length=765, blank=True)
841 position = models.CharField(max_length=54, blank=True)
842 flags = models.CharField(max_length=18)
843 class Meta:
844 db_table = 'group_members'
845
846 def __str__(self):
847 return "%s to %s" % (self.account.hruid, self.asso.name)
848
849
850 @python_2_unicode_compatible
851 class GroupMemberSubRequest(models.Model):
852 asso = models.ForeignKey(Group)
853 account = models.ForeignKey(Account, db_column='uid')
854 pkey = models.CompositeField(asso, account, primary_key=True)
855
856 ts = models.DateTimeField()
857 reason = models.TextField(blank=True)
858 class Meta:
859 db_table = 'group_member_sub_requests'
860
861 def __str__(self):
862 return "%s to %s" % (self.account.hruid, self.asso.name)
863
864
865 @python_2_unicode_compatible
866 class GroupFormerMember(models.Model):
867 asso = models.ForeignKey(Group)
868 account = models.ForeignKey(Account, db_column='uid')
869 pkey = models.CompositeField(asso, account, primary_key=True)
870
871 remember = models.IntegerField()
872 unsubsciption_date = models.DateField()
873 class Meta:
874 db_table = 'group_former_members'
875
876 def __str__(self):
877 return "%s to %s" % (self.account.hruid, self.asso.name)
878
879
880 # Group::Announces
881 # ----------------
882
883
884 @python_2_unicode_compatible
885 class GroupAnnounce(models.Model):
886 #id = models.IntegerField(primary_key=True)
887 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
888 asso = models.ForeignKey(Group)
889 create_date = models.DateTimeField()
890 titre = models.CharField(max_length=765)
891 texte = models.TextField()
892 contacts = models.TextField()
893 expiration = models.DateField()
894 promo_min = models.IntegerField()
895 promo_max = models.IntegerField()
896 flags = models.CharField(max_length=36)
897 post_id = models.IntegerField(null=True, blank=True,
898 help_text=u"NNTP post ID")
899 class Meta:
900 db_table = 'group_announces'
901
902 def __str__(self):
903 return "%s: %s" % (self.asso.name, self.titre)
904
905
906 @python_2_unicode_compatible
907 class GroupAnnouncePhoto(models.Model):
908 eid = models.ForeignKey(GroupAnnounce, primary_key=True, db_column='eid')
909 attachmime = models.CharField(max_length=12)
910 attach = models.TextField()
911 x = models.IntegerField()
912 y = models.IntegerField()
913 class Meta:
914 db_table = 'group_announces_photo'
915
916 def __str__(self):
917 return "%s (%s, %d x %d)" % (self.eid, self.attachmime, self.x, self.y)
918
919
920 @python_2_unicode_compatible
921 class GroupAnnounceRead(models.Model):
922 announce = models.ForeignKey(GroupAnnounce)
923 account = models.ForeignKey(Account, db_column='uid')
924 pkey = models.CompositeField(announce, account, primary_key=True)
925 class Meta:
926 db_table = 'group_announces_read'
927
928 def __str__(self):
929 return "%s: %s" % (self.account.hruid, self.announce_id)
930
931
932 # Group::Event
933 # ------------
934
935
936 @python_2_unicode_compatible
937 class GroupEvent(models.Model):
938 eid = models.IntegerField(primary_key=True)
939 asso = models.ForeignKey(Group, null=True, blank=True)
940 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
941 intitule = models.CharField(max_length=300)
942 short_name = models.CharField(max_length=90)
943 paiement = models.ForeignKey(Payment, null=True, blank=True)
944 descriptif = models.TextField()
945 debut = models.DateTimeField()
946 fin = models.DateTimeField(null=True, blank=True)
947 show_participants = models.BooleanField()
948 deadline_inscription = models.DateField(null=True, blank=True)
949 noinvite = models.IntegerField()
950 accept_nonmembre = models.BooleanField()
951 archive = models.BooleanField()
952 subscription_notification = models.CharField(max_length=24)
953 class Meta:
954 db_table = 'group_events'
955
956 def __str__(self):
957 return "%s: %s" % (self.asso.name, self.intitule)
958
959
960 @python_2_unicode_compatible
961 class GroupEventItem(models.Model):
962 event = models.ForeignKey(GroupEvent, db_column='eid')
963 item_id = models.IntegerField()
964 pkey = models.CompositeField(event, item_id, primary_key=True)
965
966 titre = models.CharField(max_length=300)
967 details = models.TextField()
968 montant = models.DecimalField(max_digits=12, decimal_places=2)
969 class Meta:
970 db_table = 'group_event_items'
971
972 def __str__(self):
973 return "%s - %s" % (self.event, self.item_id)
974
975
976 @python_2_unicode_compatible
977 class GroupEventParticipant(models.Model):
978 event = models.ForeignKey(GroupEvent, db_column='eid')
979 item_id = models.IntegerField()
980 account = models.ForeignKey(Account, db_column='uid')
981 item = models.ForeignKey(GroupEventItem, to_field='pkey')
982 pkey = models.CompositeField(event, account, item, primary_key=True)
983
984 nb = models.IntegerField()
985 flags = models.CharField(max_length=42)
986 paid = models.FloatField()
987 class Meta:
988 db_table = 'group_event_participants'
989
990 def __str__(self):
991 return "%s to %s" % (self.account.hruid, self.item)
992
993
994 # Group::misc
995 # -----------
996
997
998 @python_2_unicode_compatible
999 class GroupAuth(models.Model):
1000 #id = models.IntegerField(primary_key=True)
1001 privkey = models.CharField(max_length=120, unique=True)
1002 name = models.CharField(max_length=96)
1003 datafields = models.CharField(max_length=765)
1004 returnurls = models.CharField(max_length=765)
1005 last_used = models.DateField(null=True, blank=True)
1006 group = models.ForeignKey(Group, null=True, blank=True)
1007 flags = models.CharField(max_length=63, blank=True)
1008 class Meta:
1009 db_table = 'group_auth'
1010
1011 def __str__(self):
1012 return self.name
1013
1014
1015 # Logging
1016 # =======
1017
1018
1019 @python_2_unicode_compatible
1020 class IpWatch(models.Model):
1021 state = models.CharField(max_length=27)
1022 detection = models.DateField(null=True, blank=True)
1023 last = models.DateTimeField()
1024 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
1025 description = models.TextField()
1026 ip = models.IntegerField(primary_key=True)
1027 mask = models.IntegerField()
1028 class Meta:
1029 db_table = 'ip_watch'
1030
1031 def __str__(self):
1032 return self.ip
1033
1034
1035 @python_2_unicode_compatible
1036 class LogAction(models.Model):
1037 #id = models.IntegerField(primary_key=True)
1038 text = models.CharField(max_length=96)
1039 description = models.CharField(max_length=765)
1040 class Meta:
1041 db_table = 'log_actions'
1042
1043 def __str__(self):
1044 return self.text
1045
1046
1047 @python_2_unicode_compatible
1048 class LogSession(models.Model):
1049 #id = models.IntegerField(primary_key=True)
1050 auth = models.CharField(max_length=18)
1051 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True, related_name='sessions')
1052 start = models.DateTimeField()
1053 host = models.CharField(max_length=384)
1054 sauth = models.CharField(max_length=18)
1055 suid = models.ForeignKey(Account, null=True, db_column='suid', blank=True, related_name='su_sessions')
1056 browser = models.CharField(max_length=765)
1057 forward_host = models.CharField(max_length=384, blank=True)
1058 flags = models.CharField(max_length=15)
1059 ip = models.IntegerField()
1060 forward_ip = models.IntegerField(null=True, blank=True)
1061 class Meta:
1062 db_table = 'log_sessions'
1063
1064 def __str__(self):
1065 return "%s: %s@%s" % (self.id, self.account.hruid, self.host)
1066
1067
1068 @python_2_unicode_compatible
1069 class LogLastSession(models.Model):
1070 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
1071 id = models.ForeignKey(LogSession, db_column='id')
1072 class Meta:
1073 db_table = 'log_last_sessions'
1074
1075 def __str__(self):
1076 return self.account.hruid
1077
1078
1079 @python_2_unicode_compatible
1080 class LogEvent(models.Model):
1081 stamp = models.DateTimeField(primary_key=True)
1082 session = models.ForeignKey(LogSession, db_column='session')
1083 action = models.ForeignKey(LogAction, db_column='action')
1084 data = models.TextField(blank=True)
1085 class Meta:
1086 db_table = 'log_events'
1087
1088 def __str__(self):
1089 return "%s@%s: %s" % (self.session_id, self.stamp, self.action.text)
1090
1091
1092 # Newsletters
1093 # ===========
1094
1095
1096 @python_2_unicode_compatible
1097 class Newsletter(models.Model):
1098 #id = models.IntegerField(primary_key=True)
1099 group = models.ForeignKey(Group, unique=True)
1100 name = models.CharField(max_length=765)
1101 criteria = models.CharField(max_length=42, blank=True)
1102 class Meta:
1103 db_table = 'newsletters'
1104
1105 def __str__(self):
1106 return self.name
1107
1108
1109 @python_2_unicode_compatible
1110 class NewsletterIssue(models.Model):
1111 nlid = models.ForeignKey(Newsletter, unique=True, db_column='nlid')
1112 #id = models.IntegerField(primary_key=True)
1113 date = models.DateField()
1114 send_before = models.DateTimeField(null=True, blank=True)
1115 state = models.CharField(max_length=21)
1116 sufb_json = models.TextField(blank=True)
1117 title = models.CharField(max_length=765)
1118 head = models.TextField()
1119 signature = models.TextField()
1120 short_name = models.CharField(max_length=48, unique=True, blank=True)
1121 mail_title = models.CharField(max_length=765)
1122 unsubscribe = models.IntegerField()
1123 reply_to = models.CharField(max_length=765)
1124 class Meta:
1125 db_table = 'newsletter_issues'
1126
1127 def __str__(self):
1128 return self.title
1129
1130
1131 @python_2_unicode_compatible
1132 class NewsletterCat(models.Model):
1133 cid = models.AutoField(primary_key=True)
1134 nlid = models.ForeignKey(Newsletter, db_column='nlid')
1135 pos = models.IntegerField()
1136 title = models.CharField(max_length=384)
1137 class Meta:
1138 db_table = 'newsletter_cat'
1139
1140 def __str__(self):
1141 return self.title
1142
1143
1144 @python_2_unicode_compatible
1145 class NewsletterArt(models.Model):
1146 issue = models.ForeignKey(NewsletterIssue, db_column='id')
1147 aid = models.IntegerField()
1148 pkey = models.CompositeField(issue, aid, primary_key=True)
1149 cid = models.ForeignKey(NewsletterCat, null=True, db_column='cid', blank=True)
1150 pos = models.IntegerField()
1151 title = models.TextField()
1152 body = models.TextField()
1153 append = models.TextField()
1154 class Meta:
1155 db_table = 'newsletter_art'
1156
1157 def __str__(self):
1158 return "%s: %s" % (self.issue_id, self.title)
1159
1160
1161 @python_2_unicode_compatible
1162 class NewsletterIns(models.Model):
1163 account = models.ForeignKey(Account, db_column='uid')
1164 nl = models.ForeignKey(Newsletter, db_column='nlid')
1165 pkey = models.CompositeField(account, nl, primary_key=True)
1166 last = models.ForeignKey(NewsletterIssue, null=True, db_column='last', blank=True)
1167 hash = models.CharField(max_length=96, blank=True)
1168 class Meta:
1169 db_table = 'newsletter_ins'
1170
1171 def __str__(self):
1172 return "%s to %s" % (self.account.hruid, self.nl.title)
1173
1174
1175 # Profile
1176 # =======
1177
1178
1179 @python_2_unicode_compatible
1180 class ProfileDisplay(models.Model):
1181 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1182 yourself = models.CharField(max_length=765)
1183 public_name = models.CharField(max_length=765)
1184 private_name = models.CharField(max_length=765)
1185 directory_name = models.CharField(max_length=765)
1186 short_name = models.CharField(max_length=765)
1187 sort_name = models.CharField(max_length=765)
1188 promo = models.CharField(max_length=765)
1189 class Meta:
1190 db_table = 'profile_display'
1191
1192 def __str__(self):
1193 return self.profile.hrpid
1194
1195
1196 @python_2_unicode_compatible
1197 class ProfilePhone(models.Model):
1198 LINK_ADDRESS = 'address'
1199 LINK_PRO = 'pro'
1200 LINK_USER = 'user'
1201 LINK_HQ = 'hq'
1202 LINK_GROUP = 'group'
1203 LINK_CHOICES = (
1204 (LINK_ADDRESS, u"Address"),
1205 (LINK_PRO, u"Pro"),
1206 (LINK_USER, u"User"),
1207 (LINK_HQ, u"HQ"),
1208 (LINK_GROUP, u"Group"),
1209 )
1210
1211 KIND_FIXED = 'fixed'
1212 KIND_MOBILE = 'mobile'
1213 KIND_FAX = 'fax'
1214 KIND_CHOICES = (
1215 (KIND_FIXED, u"Fixed"),
1216 (KIND_MOBILE, u"Mobile"),
1217 (KIND_FAX, u"Fax"),
1218 )
1219
1220 profile = models.ForeignKey(Profile, db_column='pid', related_name='phones')
1221 link_type = models.CharField(max_length=21, choices=LINK_CHOICES)
1222 link_id = models.IntegerField()
1223 tel_id = models.IntegerField()
1224 pkey = models.CompositeField(profile, link_type, link_id, tel_id, primary_key=True)
1225
1226 tel_type = models.CharField(max_length=18, choices=KIND_CHOICES)
1227 search_tel = models.CharField(max_length=75)
1228 display_tel = models.CharField(max_length=90)
1229 pub = models.CharField(max_length=21)
1230 comment = models.CharField(max_length=240)
1231
1232 class Meta:
1233 db_table = 'profile_phones'
1234
1235 def __str__(self):
1236 return "%s: %s (%s)" % (self.profile.hrpid, self.display_tel, self.tel_type)
1237
1238 @property
1239 def is_address(self):
1240 return self.link_type == self.LINK_ADDRESS
1241
1242 @property
1243 def is_job(self):
1244 return self.link_type == self.LINK_PRO
1245
1246 @property
1247 def ax_visible(self):
1248 return is_ax_visible(self.pub)
1249
1250
1251 @python_2_unicode_compatible
1252 class ProfilePhoto(models.Model):
1253 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid', related_name='photo')
1254 attachmime = models.CharField(max_length=12)
1255 attach = models.TextField()
1256 x = models.IntegerField()
1257 y = models.IntegerField()
1258 pub = models.CharField(max_length=21)
1259 last_update = models.DateTimeField()
1260 class Meta:
1261 db_table = 'profile_photos'
1262
1263 def __str__(self):
1264 return self.profile.hrpid
1265
1266
1267 @python_2_unicode_compatible
1268 class ProfilePrivateName(models.Model):
1269 profile = models.ForeignKey(Profile, db_column='pid', related_name='private_name')
1270 type = models.CharField(max_length=27)
1271 id = models.IntegerField()
1272 pkey = models.CompositeField(profile, type, id, primary_key=True)
1273 name = models.CharField(max_length=765)
1274 class Meta:
1275 db_table = 'profile_private_names'
1276
1277 def __str__(self):
1278 return "%s: %s" % (self.profile.hrpid, self.type)
1279
1280
1281 @python_2_unicode_compatible
1282 class ProfilePublicName(models.Model):
1283 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid', related_name='public_name')
1284 lastname_initial = models.CharField(max_length=765)
1285 lastname_main = models.CharField(max_length=765)
1286 lastname_marital = models.CharField(max_length=765)
1287 lastname_ordinary = models.CharField(max_length=765)
1288 firstname_initial = models.CharField(max_length=765)
1289 firstname_main = models.CharField(max_length=765)
1290 firstname_ordinary = models.CharField(max_length=765)
1291 pseudonym = models.CharField(max_length=765)
1292 class Meta:
1293 db_table = 'profile_public_names'
1294
1295 def __str__(self):
1296 return self.profile.hrpid
1297
1298
1299 # Profile::addresses
1300 # ------------------
1301
1302
1303 @python_2_unicode_compatible
1304 class ProfileAddress(models.Model):
1305
1306 KIND_HOME = 'home'
1307 KIND_HQ = 'hq'
1308 KIND_JOB = 'job'
1309 KIND_GROUP = 'group'
1310
1311 KIND_CHOICES = (
1312 (KIND_HOME, u"Home"),
1313 (KIND_HQ, u"Headquarters"),
1314 (KIND_JOB, u"Job"),
1315 (KIND_GROUP, u"Group"),
1316 )
1317
1318 profile = models.ForeignKey(Profile, db_column='pid', related_name='addresses')
1319 job = models.ForeignKey('ProfileJobEnum', db_column='jobid', blank=True, null=True,
1320 related_name='addresses')
1321 #job = models.IntegerField(db_column='jobid')
1322 group = models.ForeignKey('Group', db_column='groupid', blank=True, null=True)
1323 #groupid = models.IntegerField()
1324 addr_type = models.CharField(max_length=15, db_column='type', choices=KIND_CHOICES)
1325 subid = models.IntegerField(db_column='id')
1326 pkey = models.CompositeField(profile, job, group, addr_type, subid, primary_key=True)
1327 pjob_key = models.CompositeField(profile, subid)
1328 pjob = models.ForeignKey('ProfileJob', aux_field='pjob_key')
1329
1330 flags = models.CharField(max_length=180, blank=True)
1331 text = models.TextField()
1332 postaltext = models.TextField(db_column='postalText') # Field name made lowercase.
1333 formatted_address = models.TextField()
1334 types = models.CharField(max_length=891)
1335 latitude = models.FloatField(null=True, blank=True)
1336 longitude = models.FloatField(null=True, blank=True)
1337 southwest_latitude = models.FloatField(null=True, blank=True)
1338 southwest_longitude = models.FloatField(null=True, blank=True)
1339 northeast_latitude = models.FloatField(null=True, blank=True)
1340 northeast_longitude = models.FloatField(null=True, blank=True)
1341 location_type = models.CharField(max_length=54, blank=True)
1342 partial_match = models.IntegerField()
1343 pub = models.CharField(max_length=21)
1344 comment = models.CharField(max_length=765, blank=True)
1345 geocoding_date = models.DateField(null=True, blank=True)
1346 geocoding_calls = models.IntegerField()
1347 postal_code_fr = models.CharField(max_length=15, blank=True)
1348
1349 components = models.ManyToManyField('ProfileAddressComponentEnum',
1350 through='ProfileAddressComponent', related_name='addresses')
1351
1352 class Meta:
1353 db_table = 'profile_addresses'
1354
1355 def __str__(self):
1356 if self.addr_type == self.KIND_HOME:
1357 rel = self.profile.hrpid
1358 elif self.addr_type == self.KIND_HQ:
1359 if self.jobid:
1360 rel = unicode(self.job)
1361 else:
1362 rel = u"[BADJOB]"
1363 elif self.addr_type == self.KIND_GROUP:
1364 rel = unicode(self.group)
1365 else:
1366 rel = u"%s at %s" % (self.profile.hrpid, self.pjob.company)
1367 return "%s address %d for %s" % (
1368 self.get_addr_type_display(), self.subid, rel)
1369
1370 @property
1371 def ax_visible(self):
1372 return is_ax_visible(self.pub)
1373
1374 def get_components_by_type(self):
1375 flags = collections.defaultdict(list)
1376 for component in self.components.all():
1377 for cp_type in component.types.split(','):
1378 flags[cp_type].append(component)
1379 return flags
1380
1381 @property
1382 def flag_list(self):
1383 return self.flags.split(',')
1384
1385 FLAG_CURRENT = 'current'
1386 FLAG_MAIL = 'mail'
1387 FLAG_SECONDARY = 'secondary'
1388
1389 @property
1390 def current(self):
1391 return self.FLAG_CURRENT in self.flag_list
1392
1393 @property
1394 def mail(self):
1395 return self.FLAG_MAIL in self.flag_list
1396
1397 @property
1398 def secondary(self):
1399 return self.FLAG_SECONDARY in self.flag_list
1400
1401 @property
1402 def is_home(self):
1403 return self.addr_type == self.KIND_HOME
1404
1405 @property
1406 def is_job(self):
1407 return self.addr_type == self.KIND_JOB
1408
1409
1410 @python_2_unicode_compatible
1411 class ProfileAddressComponentEnum(models.Model):
1412 #id = models.BigIntegerField(primary_key=True)
1413 short_name = models.CharField(max_length=765)
1414 long_name = models.CharField(max_length=765)
1415 types = models.CharField(max_length=891)
1416 class Meta:
1417 db_table = 'profile_addresses_components_enum'
1418
1419 def __str__(self):
1420 return '%s (%s)' % (self.short_name, self.types)
1421
1422
1423 @python_2_unicode_compatible
1424 class ProfileAddressComponent(models.Model):
1425 profile = models.ForeignKey(Profile, db_column='pid')
1426 job = models.ForeignKey('ProfileJobEnum', db_column='jobid')
1427 group = models.ForeignKey(Group, db_column='groupid', blank=True, null=True)
1428 addr_type = models.CharField(max_length=15, db_column='type')
1429 subid = models.IntegerField(db_column='id')
1430 pkey = models.CompositeField(profile, job, group, addr_type, subid, primary_key=True)
1431
1432 component = models.ForeignKey(ProfileAddressComponentEnum, related_name='component_links')
1433 address = models.ForeignKey(ProfileAddress, related_name='component_links',
1434 aux_field='pkey')
1435 class Meta:
1436 db_table = 'profile_addresses_components'
1437
1438 def __str__(self):
1439 return "%s (%s) for %s" % (
1440 self.component.long_name,
1441 self.component.types,
1442 self.address,
1443 )
1444
1445
1446 # Profile::networking
1447 # -------------------
1448
1449
1450 class ProfileBinetEnum(models.Model):
1451 #id = models.IntegerField(primary_key=True)
1452 text = models.CharField(max_length=150)
1453 url = models.CharField(max_length=765)
1454 class Meta:
1455 db_table = 'profile_binet_enum'
1456
1457
1458 class ProfileBinet(models.Model):
1459 profile = models.ForeignKey(Profile, db_column='pid')
1460 binet = models.ForeignKey(ProfileBinetEnum)
1461 pkey = models.CompositeField(profile, binet, primary_key=True)
1462 class Meta:
1463 db_table = 'profile_binets'
1464
1465
1466 class ProfileHobby(models.Model):
1467 profile = models.ForeignKey(Profile, db_column='pid')
1468 id = models.IntegerField()
1469 pkey = models.CompositeField(profile, id, primary_key=True)
1470 type = models.CharField(max_length=18)
1471 text = models.CharField(max_length=765)
1472 pub = models.CharField(max_length=21)
1473 class Meta:
1474 db_table = 'profile_hobby'
1475
1476
1477 class ProfileNetworkingEnum(models.Model):
1478 nwid = models.IntegerField(primary_key=True)
1479 name = models.CharField(max_length=90)
1480 icon = models.CharField(max_length=150)
1481 filter = models.CharField(max_length=18)
1482 network_type = models.CharField(max_length=18)
1483 link = models.CharField(max_length=765)
1484 class Meta:
1485 db_table = 'profile_networking_enum'
1486
1487
1488 class ProfileNetworking(models.Model):
1489 profile = models.ForeignKey(Profile, db_column='pid')
1490 id = models.IntegerField()
1491 nwid = models.ForeignKey(ProfileNetworkingEnum, db_column='nwid')
1492 pkey = models.CompositeField(id, nwid, primary_key=True)
1493 address = models.CharField(max_length=765)
1494 pub = models.CharField(max_length=21)
1495 class Meta:
1496 db_table = 'profile_networking'
1497
1498
1499 # Profile::corps
1500 # --------------
1501
1502
1503 @python_2_unicode_compatible
1504 class ProfileCorpsEnum(models.Model):
1505 #id = models.IntegerField(primary_key=True)
1506 name = models.CharField(max_length=255, unique=True)
1507 abbreviation = models.CharField(max_length=15, unique=True)
1508 still_exists = models.IntegerField()
1509 class Meta:
1510 db_table = 'profile_corps_enum'
1511
1512 def __str__(self):
1513 return self.name
1514
1515
1516 @python_2_unicode_compatible
1517 class ProfileCorpsRankEnum(models.Model):
1518 #id = models.IntegerField(primary_key=True)
1519 name = models.CharField(max_length=255, unique=True)
1520 abbreviation = models.CharField(max_length=15, unique=True)
1521 class Meta:
1522 db_table = 'profile_corps_rank_enum'
1523
1524 def __str__(self):
1525 return self.name
1526
1527
1528 @python_2_unicode_compatible
1529 class ProfileCorps(models.Model):
1530 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1531 original = models.ForeignKey(ProfileCorpsEnum, db_column='original_corpsid', related_name='original_members')
1532 current = models.ForeignKey(ProfileCorpsEnum, db_column='current_corpsid', related_name='current_members')
1533 rank = models.ForeignKey(ProfileCorpsRankEnum, db_column='rankid')
1534 # Ignored: corps is public information anyway.
1535 corps_pub = models.CharField(max_length=21)
1536 class Meta:
1537 db_table = 'profile_corps'
1538
1539 def __str__(self):
1540 return "%s: %s" % (self.profile.hrpid, self.current.name)
1541
1542
1543 # Profile::edu
1544 # ------------
1545
1546
1547 @python_2_unicode_compatible
1548 class ProfileEducationEnum(models.Model):
1549 #id = models.IntegerField(primary_key=True)
1550 name = models.CharField(max_length=255, unique=True, blank=True)
1551 abbreviation = models.CharField(max_length=765)
1552 url = models.CharField(max_length=765, blank=True)
1553 country = models.ForeignKey(GeolocCountry, null=True, db_column='country', blank=True)
1554 class Meta:
1555 db_table = 'profile_education_enum'
1556
1557 def __str__(self):
1558 return self.name
1559
1560 @property
1561 def short(self):
1562 return self.abbreviation or self.name
1563
1564
1565 @python_2_unicode_compatible
1566 class ProfileEducationDegreeEnum(models.Model):
1567 #id = models.IntegerField(primary_key=True)
1568 degree = models.CharField(max_length=255, unique=True, blank=True)
1569 abbreviation = models.CharField(max_length=765)
1570 level = models.IntegerField()
1571 class Meta:
1572 db_table = 'profile_education_degree_enum'
1573
1574 def __str__(self):
1575 return self.degree
1576
1577
1578 @python_2_unicode_compatible
1579 class ProfileEducationFieldEnum(models.Model):
1580 #id = models.IntegerField(primary_key=True)
1581 field = models.CharField(max_length=255, unique=True, blank=True)
1582 class Meta:
1583 db_table = 'profile_education_field_enum'
1584
1585 def __str__(self):
1586 return self.field
1587
1588
1589 @python_2_unicode_compatible
1590 class ProfileEducation(models.Model):
1591 id = models.IntegerField()
1592 profile = models.ForeignKey(Profile, db_column='pid', related_name='educations')
1593 pkey = models.CompositeField(id, profile, primary_key=True)
1594
1595 school = models.ForeignKey(ProfileEducationEnum, null=True, db_column='eduid', blank=True)
1596 degree = models.ForeignKey(ProfileEducationDegreeEnum, null=True, db_column='degreeid', blank=True)
1597 field = models.ForeignKey(ProfileEducationFieldEnum, null=True, db_column='fieldid', blank=True)
1598 entry_year = models.IntegerField(null=True, blank=True)
1599 grad_year = models.IntegerField(null=True, blank=True)
1600 promo_year = models.IntegerField(null=True, blank=True)
1601 program = models.CharField(max_length=765, blank=True)
1602 flags = models.CharField(max_length=81)
1603 class Meta:
1604 db_table = 'profile_education'
1605
1606 def __str__(self):
1607 return "%s: %s" % (self.profile.hrpid, self.edu.name)
1608
1609
1610 @python_2_unicode_compatible
1611 class ProfileEducationDegree(models.Model):
1612 edu = models.ForeignKey(ProfileEducationEnum, db_column='eduid')
1613 degree = models.ForeignKey(ProfileEducationDegreeEnum, db_column='degreeid')
1614 pkey = models.CompositeField(edu, degree, primary_key=True)
1615 class Meta:
1616 db_table = 'profile_education_degree'
1617
1618 def __str__(self):
1619 return "%s - %s" % (self.edu, self.degree)
1620
1621
1622 # Profile::jobs
1623 # -------------
1624
1625
1626 @python_2_unicode_compatible
1627 class ProfileJobEnum(models.Model):
1628 #id = models.IntegerField(primary_key=True)
1629 name = models.CharField(max_length=255, unique=True)
1630 acronym = models.CharField(max_length=765, blank=True)
1631 url = models.CharField(max_length=765, blank=True)
1632 email = models.CharField(max_length=765, blank=True)
1633 holding = models.ForeignKey('self', null=True, db_column='holdingid', blank=True)
1634 naf_code = models.CharField(max_length=15, db_column='NAF_code', blank=True) # Field name made lowercase.
1635 ax_code = models.BigIntegerField(null=True, db_column='AX_code', blank=True) # Field name made lowercase.
1636 siren_code = models.CharField(max_length=9, null=True, db_column='SIREN_code', blank=True) # Field name made lowercase.
1637 class Meta:
1638 db_table = 'profile_job_enum'
1639
1640 def __str__(self):
1641 return self.name
1642
1643 @property
1644 def address(self):
1645 if not hasattr(self, '_address'):
1646
1647 self._address = None
1648 for address in self.addresses.all():
1649 if address.addr_type == address.KIND_HQ:
1650 self._address = address
1651 break
1652 return self._address
1653
1654
1655 @python_2_unicode_compatible
1656 class ProfileJob(models.Model):
1657 id = models.IntegerField()
1658 profile = models.ForeignKey(Profile, db_column='pid', related_name='jobs')
1659 pkey = models.CompositeField(profile, id, primary_key=True)
1660
1661 company = models.ForeignKey(ProfileJobEnum, null=True, db_column='jobid', blank=True)
1662 description = models.CharField(max_length=765)
1663 url = models.CharField(max_length=765)
1664 email = models.CharField(max_length=765)
1665 pub = models.CharField(max_length=21)
1666 email_pub = models.CharField(max_length=21)
1667 entry_year = models.CharField(max_length=12, blank=True)
1668 class Meta:
1669 db_table = 'profile_job'
1670
1671 @property
1672 def ax_visible(self):
1673 return is_ax_visible(self.pub)
1674
1675 @property
1676 def ax_visible_email(self):
1677 return is_ax_visible(self.email_pub)
1678
1679 def __str__(self):
1680 return "%s at %s" % (self.profile.hrpid, self.company.name if self.company else '<NONE>')
1681
1682
1683 # Profile::job::terms
1684 # -------------------
1685
1686
1687 @python_2_unicode_compatible
1688 class ProfileJobTermEnum(models.Model):
1689 jtid = models.AutoField(primary_key=True)
1690 name = models.CharField(max_length=765)
1691 full_name = models.CharField(max_length=765)
1692 class Meta:
1693 db_table = 'profile_job_term_enum'
1694
1695 def __str__(self):
1696 return self.name
1697
1698
1699 @python_2_unicode_compatible
1700 class ProfileJobTermRelation(models.Model):
1701 jtid_1 = models.ForeignKey(ProfileJobTermEnum, db_column='jtid_1', related_name='relations_from')
1702 jtid_2 = models.ForeignKey(ProfileJobTermEnum, db_column='jtid_2', related_name='relations_to')
1703 rel = models.CharField(max_length=24)
1704 computed = models.CharField(max_length=24)
1705 pkey = models.CompositeField(jtid_1, jtid_2, computed, primary_key=True)
1706 class Meta:
1707 db_table = 'profile_job_term_relation'
1708
1709 def __str__(self):
1710 return "%s <-> %s" % (self.jtid_1.name, self.jtid_2.name)
1711
1712
1713 @python_2_unicode_compatible
1714 class ProfileJobTermSearch(models.Model):
1715 search = models.CharField(max_length=150)
1716 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1717 pkey = models.CompositeField(search, job_term, primary_key=True)
1718 class Meta:
1719 db_table = 'profile_job_term_search'
1720
1721 def __str__(self):
1722 return "%s => %s" % (self.search, self.job_term.name)
1723
1724
1725 @python_2_unicode_compatible
1726 class ProfileJobTerm(models.Model):
1727 profile = models.ForeignKey(Profile, db_column='pid')
1728 company = models.ForeignKey(ProfileJobEnum, db_column='jid')
1729 job = models.ForeignKey(ProfileJob, to_field='pkey')
1730 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1731 computed = models.CharField(max_length=24)
1732 pkey = models.CompositeField(profile, company, job_term, primary_key=True)
1733 class Meta:
1734 db_table = 'profile_job_term'
1735
1736 def __str__(self):
1737 return "%s at %s: %s" % (self.profile.hrpid, self.company.name, self.job_term.name)
1738
1739
1740 @python_2_unicode_compatible
1741 class ProfileJobEntrepriseTerm(models.Model):
1742 job = models.ForeignKey(ProfileJobEnum, db_column='eid')
1743 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1744 pkey = models.CompositeField(job, job_term, primary_key=True)
1745 class Meta:
1746 db_table = 'profile_job_entreprise_term'
1747
1748 def __str__(self):
1749 return "%s: %s" % (self.job.name, self.job_term.name)
1750
1751
1752 # Profile::skills
1753 # ---------------
1754
1755
1756 @python_2_unicode_compatible
1757 class ProfileLangSkillEnum(models.Model):
1758 iso_639_2b = models.CharField(max_length=9, primary_key=True)
1759 language = models.CharField(max_length=765)
1760 language_en = models.CharField(max_length=765)
1761 iso_639_2t = models.CharField(max_length=9)
1762 iso_639_1 = models.CharField(max_length=6, blank=True)
1763 class Meta:
1764 db_table = 'profile_langskill_enum'
1765
1766 def __str__(self):
1767 return self.iso_639_2b
1768
1769
1770 @python_2_unicode_compatible
1771 class ProfileLangSkill(models.Model):
1772 profile = models.ForeignKey(Profile, db_column='pid')
1773 lang = models.ForeignKey(ProfileLangSkillEnum, db_column='lid')
1774 pkey = models.CompositeField(profile, lang, primary_key=True)
1775 level = models.IntegerField(null=True, blank=True)
1776 class Meta:
1777 db_table = 'profile_langskills'
1778
1779 def __str__(self):
1780 return "%s: %s" % (self.profile.hrpid, self.lang.iso_639_2b)
1781
1782
1783 @python_2_unicode_compatible
1784 class ProfileSkillEnum(models.Model):
1785 id = models.CharField(max_length=9, primary_key=True)
1786 text_fr = models.CharField(max_length=330)
1787 text_en = models.CharField(max_length=330)
1788 flags = models.CharField(max_length=15)
1789 axfreetext = models.TextField()
1790 class Meta:
1791 db_table = 'profile_skill_enum'
1792
1793 def __str__(self):
1794 return self.text_en
1795
1796
1797 @python_2_unicode_compatible
1798 class ProfileSkill(models.Model):
1799 profile = models.ForeignKey(Profile, db_column='pid')
1800 skill = models.ForeignKey(ProfileSkillEnum, db_column='cid')
1801 pkey = models.CompositeField(profile, skill, primary_key=True)
1802 level = models.CharField(max_length=54)
1803 class Meta:
1804 db_table = 'profile_skills'
1805
1806 def __str__(self):
1807 return "%s: %s" % (self.profile.hrpid, self.skill.text_en)
1808
1809
1810 # Profile::medals
1811 # ---------------
1812
1813
1814 class ProfileMedalEnum(models.Model):
1815 #id = models.IntegerField(primary_key=True)
1816 type = models.CharField(max_length=30)
1817 text = models.CharField(max_length=765, blank=True)
1818 img = models.CharField(max_length=765, blank=True)
1819 flags = models.CharField(max_length=63)
1820 class Meta:
1821 db_table = 'profile_medal_enum'
1822
1823
1824 class ProfileMedalGradeEnum(models.Model):
1825 medal = models.ForeignKey(ProfileMedalEnum, db_column='mid')
1826 gid = models.IntegerField()
1827 pkey = models.CompositeField(medal, gid, primary_key=True)
1828 text = models.CharField(max_length=765, blank=True)
1829 pos = models.IntegerField()
1830 class Meta:
1831 db_table = 'profile_medal_grade_enum'
1832
1833
1834 class ProfileMedal(models.Model):
1835 profile = models.ForeignKey(Profile, db_column='pid')
1836 medal = models.ForeignKey(ProfileMedalEnum)
1837 gid = models.IntegerField()
1838 grade = models.ForeignKey(ProfileMedalGradeEnum, to_field='pkey')
1839 pkey = models.CompositeField(profile, medal, gid, primary_key=True)
1840 level = models.CharField(max_length=18)
1841 class Meta:
1842 db_table = 'profile_medals'
1843
1844
1845 # Profile::mentor
1846 # ---------------
1847
1848
1849 class ProfileMentor(models.Model):
1850 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1851 expertise = models.TextField()
1852 class Meta:
1853 db_table = 'profile_mentor'
1854
1855
1856 class ProfileMentorCountry(models.Model):
1857 profile = models.ForeignKey(Profile, db_column='pid')
1858 country = models.ForeignKey(GeolocCountry, db_column='country')
1859 pkey = models.CompositeField(profile, country, primary_key=True)
1860 class Meta:
1861 db_table = 'profile_mentor_country'
1862
1863
1864 class ProfileMentorTerm(models.Model):
1865 profile = models.ForeignKey(Profile, db_column='pid')
1866 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1867 pkey = models.CompositeField(profile, job_term, primary_key=True)
1868 class Meta:
1869 db_table = 'profile_mentor_term'
1870
1871
1872 # Profile::partner
1873 # ----------------
1874
1875
1876 class ProfilePartnersharingEnum(models.Model):
1877 #id = models.IntegerField(primary_key=True)
1878 api_account = models.ForeignKey(Account, null=True, db_column='api_uid', blank=True)
1879 shortname = models.CharField(max_length=192)
1880 name = models.CharField(max_length=765)
1881 url = models.CharField(max_length=765)
1882 default_sharing_level = models.CharField(max_length=21, blank=True)
1883 has_directory = models.IntegerField()
1884 has_bulkmail = models.IntegerField()
1885 class Meta:
1886 db_table = 'profile_partnersharing_enum'
1887
1888
1889 class ProfilePartnersharingSetting(models.Model):
1890 profile = models.ForeignKey(Profile, db_column='pid')
1891 partner = models.ForeignKey(ProfilePartnersharingEnum)
1892 pkey = models.CompositeField(profile, partner, primary_key=True)
1893 exposed_uid = models.CharField(max_length=765)
1894 sharing_level = models.CharField(max_length=21, blank=True)
1895 allow_email = models.CharField(max_length=18, blank=True)
1896 last_connection = models.DateTimeField(null=True, blank=True)
1897 class Meta:
1898 db_table = 'profile_partnersharing_settings'
1899
1900
1901 class ProfilePhotoToken(models.Model):
1902 profile = models.ForeignKey(Profile, primary_key=True, db_column='pid')
1903 token = models.CharField(max_length=765)
1904 expires = models.DateTimeField()
1905 class Meta:
1906 db_table = 'profile_photo_tokens'
1907
1908
1909 # Profile::misc
1910 # -------------
1911
1912
1913 class ProfileMergeIssue(models.Model):
1914 profile = models.ForeignKey(Profile, primary_key=True, db_column='pid')
1915 issues = models.CharField(max_length=144, blank=True)
1916 entry_year_ax = models.IntegerField(null=True, blank=True)
1917 deathdate_ax = models.DateField(null=True, blank=True)
1918 name = models.CharField(max_length=765, blank=True)
1919 name_type = models.IntegerField(null=True, blank=True)
1920 class Meta:
1921 db_table = 'profile_merge_issues'
1922
1923
1924 class ProfileModification(models.Model):
1925 profile = models.ForeignKey(Profile, db_column='pid')
1926 account = models.ForeignKey(Account, db_column='uid')
1927 field = models.CharField(max_length=180)
1928 pkey = models.CompositeField(profile, field, primary_key=True)
1929 oldtext = models.TextField(db_column='oldText')
1930 newtext = models.TextField(db_column='newText')
1931 type = models.CharField(max_length=33)
1932 timestamp = models.DateTimeField()
1933 class Meta:
1934 db_table = 'profile_modifications'
1935
1936
1937 class ProfileVisibilityEnum(models.Model):
1938 access_level = models.CharField(max_length=21, blank=True, primary_key=True)
1939 best_display_level = models.CharField(max_length=21, blank=True)
1940 display_levels = models.CharField(max_length=72, blank=True)
1941 class Meta:
1942 db_table = 'profile_visibility_enum'
1943
1944
1945
1946 class ProfileDeltaten(models.Model):
1947 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1948 message = models.TextField()
1949 class Meta:
1950 db_table = 'profile_deltaten'
1951
1952
1953 # Reminders
1954 # =========
1955
1956
1957 class ReminderType(models.Model):
1958 #type_id = models.IntegerField(primary_key=True)
1959 name = models.CharField(max_length=255, unique=True)
1960 weight = models.IntegerField()
1961 remind_delay_yes = models.IntegerField()
1962 remind_delay_no = models.IntegerField()
1963 remind_delay_dismiss = models.IntegerField()
1964 class Meta:
1965 db_table = 'reminder_type'
1966
1967
1968 class Reminder(models.Model):
1969 account = models.ForeignKey(Account, db_column='uid')
1970 type = models.ForeignKey(ReminderType)
1971 pkey = models.CompositeField(account, type, primary_key=True)
1972 status = models.CharField(max_length=21)
1973 remind_last = models.DateTimeField()
1974 remind_next = models.DateTimeField(null=True, blank=True)
1975 class Meta:
1976 db_table = 'reminder'
1977
1978
1979 class ReminderTip(models.Model):
1980 #id = models.IntegerField(primary_key=True)
1981 title = models.CharField(max_length=192)
1982 text = models.TextField()
1983 priority = models.IntegerField()
1984 expiration = models.DateField()
1985 promo_min = models.IntegerField()
1986 promo_max = models.IntegerField()
1987 state = models.CharField(max_length=18)
1988 class Meta:
1989 db_table = 'reminder_tips'
1990
1991
1992 # Surveys
1993 # =======
1994
1995
1996 class Survey(models.Model):
1997 #id = models.IntegerField(primary_key=True)
1998 questions = models.TextField()
1999 title = models.CharField(max_length=765)
2000 description = models.TextField()
2001 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2002 end = models.DateField()
2003 mode = models.IntegerField()
2004 promos = models.CharField(max_length=765)
2005 class Meta:
2006 db_table = 'surveys'
2007
2008
2009 class SurveyVote(models.Model):
2010 #id = models.IntegerField(primary_key=True)
2011 survey = models.ForeignKey(Survey)
2012 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2013 class Meta:
2014 db_table = 'survey_votes'
2015
2016
2017 class SurveyAnswer(models.Model):
2018 #id = models.IntegerField(primary_key=True)
2019 vote = models.ForeignKey(SurveyVote)
2020 question_id = models.IntegerField()
2021 answer = models.TextField()
2022 class Meta:
2023 db_table = 'survey_answers'
2024
2025
2026 # GApps
2027 # =====
2028
2029
2030 class GappsAccount(models.Model):
2031 l_userid = models.ForeignKey(Account, null=True, db_column='l_userid', blank=True)
2032 l_sync_password = models.BooleanField(default=True)
2033 l_activate_mail_redirection = models.BooleanField(default=True)
2034 g_account_id = models.CharField(max_length=48, blank=True)
2035 g_account_name = models.CharField(max_length=255, primary_key=True)
2036 g_domain = models.CharField(max_length=120, blank=True)
2037 g_first_name = models.CharField(max_length=120)
2038 g_last_name = models.CharField(max_length=120)
2039 g_status = models.CharField(max_length=39, blank=True)
2040 g_admin = models.BooleanField()
2041 g_suspension = models.CharField(max_length=768, blank=True)
2042 r_disk_usage = models.BigIntegerField(null=True, blank=True)
2043 r_creation = models.DateField(null=True, blank=True)
2044 r_last_login = models.DateField(null=True, blank=True)
2045 r_last_webmail = models.DateField(null=True, blank=True)
2046 class Meta:
2047 db_table = 'gapps_accounts'
2048
2049
2050 class GappsNickname(models.Model):
2051 l_userid = models.ForeignKey(Account, null=True, db_column='l_userid', blank=True)
2052 g_account_name = models.CharField(max_length=768)
2053 g_nickname = models.CharField(max_length=255, primary_key=True)
2054 class Meta:
2055 db_table = 'gapps_nicknames'
2056
2057
2058 class GappsQueue(models.Model):
2059 q_id = models.AutoField(primary_key=True)
2060 q_owner = models.ForeignKey(Account, null=True, blank=True, related_name='owned_gapps_jobs')
2061 q_recipient = models.ForeignKey(Account, null=True, blank=True, related_name='received_gapps_jobs')
2062 p_entry_date = models.DateTimeField()
2063 p_notbefore_date = models.DateTimeField()
2064 p_start_date = models.DateTimeField(null=True, blank=True)
2065 p_end_date = models.DateTimeField(null=True, blank=True)
2066 p_status = models.CharField(max_length=24)
2067 p_priority = models.CharField(max_length=27)
2068 p_admin_request = models.BooleanField()
2069 j_type = models.CharField(max_length=30)
2070 j_parameters = models.TextField(blank=True)
2071 r_softfail_date = models.DateTimeField(null=True, blank=True)
2072 r_softfail_count = models.IntegerField()
2073 r_result = models.CharField(max_length=768, blank=True)
2074 class Meta:
2075 db_table = 'gapps_queue'
2076
2077
2078 class GappsReporting(models.Model):
2079 date = models.DateField(primary_key=True)
2080 num_accounts = models.IntegerField(null=True, blank=True)
2081 count_1_day_actives = models.IntegerField(null=True, blank=True)
2082 count_7_day_actives = models.IntegerField(null=True, blank=True)
2083 count_14_day_actives = models.IntegerField(null=True, blank=True)
2084 count_30_day_actives = models.IntegerField(null=True, blank=True)
2085 count_30_day_idle = models.IntegerField(null=True, blank=True)
2086 count_60_day_idle = models.IntegerField(null=True, blank=True)
2087 count_90_day_idle = models.IntegerField(null=True, blank=True)
2088 usage_in_bytes = models.BigIntegerField(null=True, blank=True)
2089 quota_in_mb = models.IntegerField(null=True, blank=True)
2090 class Meta:
2091 db_table = 'gapps_reporting'
2092
2093
2094
2095 # Watch
2096 # =====
2097
2098
2099 class Watch(models.Model):
2100 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2101 flags = models.CharField(max_length=39)
2102 actions = models.CharField(max_length=105)
2103 last = models.DateTimeField()
2104 class Meta:
2105 db_table = 'watch'
2106
2107
2108 class WatchGroup(models.Model):
2109 account = models.ForeignKey(Account, db_column='uid')
2110 group = models.ForeignKey(Group, db_column='groupid')
2111 pkey = models.CompositeField(account, group, primary_key=True)
2112 class Meta:
2113 db_table = 'watch_group'
2114
2115
2116 class WatchNonins(models.Model):
2117 account = models.ForeignKey(Account, db_column='uid', related_name='watching')
2118 watched = models.ForeignKey(Account, db_column='ni', related_name='watched_by')
2119 pkey = models.CompositeField(account, watched, primary_key=True)
2120 class Meta:
2121 db_table = 'watch_nonins'
2122
2123
2124 class WatchProfile(models.Model):
2125 profile = models.ForeignKey(Profile, db_column='pid')
2126 ts = models.DateTimeField()
2127 field = models.CharField(max_length=36)
2128 pkey = models.CompositeField(profile, field, primary_key=True)
2129 class Meta:
2130 db_table = 'watch_profile'
2131
2132
2133 class WatchPromo(models.Model):
2134 account = models.ForeignKey(Account, db_column='uid')
2135 promo = models.IntegerField()
2136 pkey = models.CompositeField(account, promo, primary_key=True)
2137 class Meta:
2138 db_table = 'watch_promo'
2139
2140
2141 # Postfix
2142 # =======
2143
2144
2145 class MxWatch(models.Model):
2146 host = models.CharField(max_length=192, primary_key=True)
2147 state = models.CharField(max_length=21, blank=True)
2148 text = models.TextField()
2149 class Meta:
2150 db_table = 'mx_watch'
2151
2152
2153 class PostfixBlacklist(models.Model):
2154 email = models.CharField(max_length=255, primary_key=True)
2155 reject_text = models.CharField(max_length=192)
2156 class Meta:
2157 db_table = 'postfix_blacklist'
2158
2159
2160 class PostfixMailseen(models.Model):
2161 crc = models.CharField(max_length=24, primary_key=True)
2162 nb = models.IntegerField()
2163 update_time = models.DateTimeField()
2164 create_time = models.DateTimeField()
2165 release = models.CharField(max_length=18)
2166 class Meta:
2167 db_table = 'postfix_mailseen'
2168
2169
2170 class PostfixWhitelist(models.Model):
2171 email = models.CharField(max_length=255, primary_key=True)
2172 class Meta:
2173 db_table = 'postfix_whitelist'
2174
2175
2176 # Register
2177 # ========
2178
2179
2180 class RegisterMarketing(models.Model):
2181 account = models.ForeignKey(Account, db_column='uid', related_name='received_marketings')
2182 sender = models.ForeignKey(Account, null=True, db_column='sender', blank=True, related_name='sent_marketings')
2183 email = models.CharField(max_length=765)
2184 pkey = models.CompositeField(account, email, primary_key=True)
2185
2186 date = models.DateField()
2187 last = models.DateField()
2188 nb = models.IntegerField()
2189 type = models.CharField(max_length=15, blank=True)
2190 hash = models.CharField(max_length=96)
2191 message = models.CharField(max_length=48)
2192 message_data = models.CharField(max_length=192, blank=True)
2193 personal_notes = models.TextField(blank=True)
2194 class Meta:
2195 db_table = 'register_marketing'
2196
2197
2198 class RegisterMstat(models.Model):
2199 account = models.OneToOneField(Account, primary_key=True, db_column='uid', related_name='received_marketings_stats')
2200 sender = models.ForeignKey(Account, null=True, db_column='sender', blank=True, related_name='sent_marketings_stats')
2201 success = models.DateField()
2202 class Meta:
2203 db_table = 'register_mstats'
2204
2205
2206 class RegisterPending(models.Model):
2207 account = models.OneToOneField(Account, primary_key=True, db_column='uid')
2208 forlife = models.CharField(max_length=255, unique=True)
2209 bestalias = models.CharField(max_length=255, unique=True)
2210 mailorg2 = models.CharField(max_length=765, blank=True)
2211 password = models.CharField(max_length=120)
2212 email = models.CharField(max_length=765)
2213 date = models.DateField()
2214 relance = models.DateField()
2215 naissance = models.DateField()
2216 hash = models.CharField(max_length=36)
2217 services = models.CharField(max_length=78)
2218 class Meta:
2219 db_table = 'register_pending'
2220
2221
2222 class RegisterPendingXnet(models.Model):
2223 account = models.ForeignKey(Account, primary_key=True, db_column='uid', related_name='pending_xnet_register')
2224 hruid = models.ForeignKey(Account, unique=True, db_column='hruid', related_name='pending_xnet_register_by_hruid')
2225 email = models.CharField(max_length=765)
2226 date = models.DateField()
2227 last_date = models.DateField(null=True, blank=True)
2228 hash = models.CharField(max_length=36)
2229 sender_name = models.CharField(max_length=765)
2230 group_name = models.CharField(max_length=765)
2231 class Meta:
2232 db_table = 'register_pending_xnet'
2233
2234
2235 class RegisterSubs(models.Model):
2236 account = models.ForeignKey(Account, db_column='uid')
2237 type = models.CharField(max_length=15)
2238 sub = models.CharField(max_length=96)
2239 domain = models.CharField(max_length=192)
2240 pkey = models.CompositeField(account, type, sub, domain, primary_key=True)
2241 class Meta:
2242 db_table = 'register_subs'
2243
2244
2245 # Search
2246 # ======
2247
2248
2249 class SearchAutocomplete(models.Model):
2250 name = models.CharField(max_length=60)
2251 query = models.CharField(max_length=300)
2252 pkey = models.CompositeField(name, query, primary_key=True)
2253 result = models.TextField()
2254 generated = models.DateTimeField()
2255 class Meta:
2256 db_table = 'search_autocomplete'
2257
2258
2259 class SearchName(models.Model):
2260 profile = models.ForeignKey(Profile, db_column='pid')
2261 token = models.CharField(max_length=765)
2262 pkey = models.CompositeField(profile, token, primary_key=True)
2263 score = models.IntegerField()
2264 soundex = models.CharField(max_length=12)
2265 flags = models.CharField(max_length=18)
2266 general_type = models.CharField(max_length=27)
2267 class Meta:
2268 db_table = 'search_name'
2269
2270
2271 # Requests
2272 # ========
2273
2274
2275 class Request(models.Model):
2276 account = models.ForeignKey(Account, db_column='uid')
2277 type = models.CharField(max_length=48)
2278 data = models.TextField()
2279 stamp = models.DateTimeField()
2280 profile = models.ForeignKey(Profile, null=True, db_column='pid', blank=True)
2281 pkey = models.CompositeField(account, stamp, type, primary_key=True)
2282 class Meta:
2283 db_table = 'requests'
2284
2285
2286 class RequestAnswer(models.Model):
2287 #id = models.IntegerField(primary_key=True)
2288 category = models.CharField(max_length=45)
2289 title = models.CharField(max_length=150)
2290 answer = models.TextField()
2291 class Meta:
2292 db_table = 'requests_answers'
2293
2294
2295 class RequestHidden(models.Model):
2296 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2297 hidden_requests = models.TextField()
2298 class Meta:
2299 db_table = 'requests_hidden'
2300
2301
2302 # Misc
2303 # ====
2304
2305
2306 class AXLetter(models.Model):
2307 #id = models.IntegerField(primary_key=True)
2308 short_name = models.CharField(max_length=48, unique=True, blank=True)
2309 subject = models.CharField(max_length=765)
2310 title = models.CharField(max_length=765)
2311 body = models.TextField()
2312 signature = models.TextField()
2313 promo_min = models.IntegerField()
2314 promo_max = models.IntegerField()
2315 subset = models.TextField(blank=True)
2316 subset_rm = models.IntegerField(null=True, blank=True)
2317 echeance = models.DateTimeField()
2318 date = models.DateField()
2319 bits = models.CharField(max_length=48)
2320 class Meta:
2321 db_table = 'axletter'
2322
2323
2324 class Carva(models.Model):
2325 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2326 url = models.CharField(max_length=765)
2327 class Meta:
2328 db_table = 'carvas'
2329
2330
2331 class Contact(models.Model):
2332 account = models.ForeignKey(Account, db_column='uid')
2333 contact = models.ForeignKey(Profile, db_column='contact')
2334 pkey = models.CompositeField(account, contact, primary_key=True)
2335 class Meta:
2336 db_table = 'contacts'
2337
2338
2339 class Downtime(models.Model):
2340 debut = models.DateTimeField()
2341 duree = models.TimeField() # This field type is a guess.
2342 resume = models.CharField(max_length=765)
2343 description = models.TextField()
2344 services = models.CharField(max_length=54)
2345 class Meta:
2346 db_table = 'downtimes'
2347
2348
2349 class EmailListModerate(models.Model):
2350 ml = models.CharField(max_length=192)
2351 domain = models.CharField(max_length=192)
2352 mid = models.IntegerField()
2353 pkey = models.CompositeField(ml, domain, mid, primary_key=True)
2354 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2355 action = models.CharField(max_length=18)
2356 ts = models.DateTimeField()
2357 message = models.TextField(blank=True)
2358 handler = models.IntegerField(null=True, blank=True)
2359 class Meta:
2360 db_table = 'email_list_moderate'
2361
2362
2363 class EmailSendSave(models.Model):
2364 account = models.OneToOneField(Account, primary_key=True, db_column='uid')
2365 data = models.TextField()
2366 class Meta:
2367 db_table = 'email_send_save'
2368
2369
2370 class EmailWatch(models.Model):
2371 email = models.CharField(max_length=180, primary_key=True)
2372 state = models.CharField(max_length=27)
2373 detection = models.DateField(null=True, blank=True)
2374 last = models.DateTimeField()
2375 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2376 description = models.TextField()
2377 class Meta:
2378 db_table = 'email_watch'
2379
2380
2381 class GeolocLanguage(models.Model):
2382 iso_3166_1_a2 = models.ForeignKey(GeolocCountry, db_column='iso_3166_1_a2')
2383 language = models.CharField(max_length=15)
2384 pkey = models.CompositeField(iso_3166_1_a2, language, primary_key=True)
2385 country = models.CharField(max_length=765, blank=True)
2386 countryplain = models.CharField(max_length=765, db_column='countryPlain', blank=True) # Field name made lowercase.
2387 class Meta:
2388 db_table = 'geoloc_languages'
2389
2390
2391 class HomonymList(models.Model):
2392 hrmid = models.CharField(max_length=765)
2393 account = models.ForeignKey(Account, db_column='uid')
2394 pkey = models.CompositeField(hrmid, account, primary_key=True)
2395 class Meta:
2396 db_table = 'homonyms_list'
2397
2398
2399 class UrlShortener(models.Model):
2400 alias = models.CharField(max_length=255, primary_key=True)
2401 url = models.TextField()
2402 class Meta:
2403 db_table = 'url_shortener'