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