In the middle of making "manage.py" at least show help
[vagrant-mail.git] / database / platal / models.py
CommitLineData
f497e0a9
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
b7bdbc35
NI
26cf. https://docs.djangoproject.com/en/dev/howto/legacy-databases/
27
f497e0a9
NI
28This requires Django to work.
29"""
27b0b59f 30from __future__ import unicode_literals
b7bdbc35 31
f497e0a9
NI
32import collections
33from django.db import models
27b0b59f 34from django.utils.encoding import python_2_unicode_compatible
f497e0a9
NI
35
36
37def is_ax_visible(field):
38 return field in ('public', 'ax')
39
40
41# Misc for Account/Profile
42# ========================
43
44
27b0b59f 45@python_2_unicode_compatible
f497e0a9 46class Skin(models.Model):
b7bdbc35 47 id = models.IntegerField(primary_key=True)
f497e0a9
NI
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)
b7bdbc35 54
f497e0a9 55 class Meta:
27b0b59f 56 db_table = 'skins'
f497e0a9 57
27b0b59f 58 def __str__(self):
f497e0a9
NI
59 return self.name
60
61
27b0b59f 62@python_2_unicode_compatible
f497e0a9 63class EmailVirtualDomain(models.Model):
b7bdbc35 64 id = models.IntegerField(primary_key=True)
f497e0a9
NI
65 name = models.CharField(max_length=765)
66 aliasing = models.ForeignKey('self', db_column='aliasing')
b7bdbc35 67
f497e0a9 68 class Meta:
27b0b59f 69 db_table = 'email_virtual_domains'
f497e0a9 70
27b0b59f 71 def __str__(self):
f497e0a9
NI
72 return self.name
73
74
27b0b59f 75@python_2_unicode_compatible
f497e0a9 76class ProfileSectionEnum(models.Model):
b7bdbc35 77 id = models.IntegerField(primary_key=True)
f497e0a9 78 text = models.CharField(max_length=150, unique=True)
b7bdbc35 79
f497e0a9 80 class Meta:
27b0b59f 81 db_table = 'profile_section_enum'
f497e0a9 82
27b0b59f 83 def __str__(self):
f497e0a9
NI
84 return self.text
85
86
27b0b59f 87@python_2_unicode_compatible
f497e0a9
NI
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.
b7bdbc35 103
f497e0a9 104 class Meta:
27b0b59f 105 db_table = 'geoloc_countries'
f497e0a9 106
27b0b59f 107 def __str__(self):
f497e0a9
NI
108 return self.iso_3166_1_a2
109
110
111# Account/Profile
112# ===============
113
114
27b0b59f 115@python_2_unicode_compatible
f497e0a9
NI
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)
b7bdbc35 120
f497e0a9 121 class Meta:
27b0b59f 122 db_table = 'account_types'
f497e0a9 123
27b0b59f 124 def __str__(self):
f497e0a9
NI
125 return self.type
126
127
27b0b59f 128@python_2_unicode_compatible
f497e0a9
NI
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)
b7bdbc35 156
f497e0a9 157 class Meta:
27b0b59f 158 db_table = 'accounts'
f497e0a9 159
27b0b59f
NI
160 def __str__(self):
161 return '%s (%s)' % (self.hruid, self.full_name)
f497e0a9
NI
162
163 @property
164 def profile(self):
165 return self.profiles.filter(perms='owner').get().profile
166
167
27b0b59f 168@python_2_unicode_compatible
f497e0a9
NI
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:
27b0b59f 187 return "Mme"
f497e0a9 188 else:
27b0b59f 189 return "M."
f497e0a9 190 elif self.kind == self.ALT_PSEUDO:
27b0b59f 191 return "Pseudonyme"
f497e0a9 192 else:
27b0b59f 193 return ""
f497e0a9
NI
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
27b0b59f 202@python_2_unicode_compatible
f497e0a9
NI
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:
27b0b59f 235 db_table = 'profiles'
f497e0a9 236
27b0b59f 237 def __str__(self):
f497e0a9
NI
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:
27b0b59f 295 return "France"
f497e0a9
NI
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
27b0b59f 403@python_2_unicode_compatible
f497e0a9
NI
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')
f497e0a9 407 perms = models.CharField(max_length=15)
b7bdbc35 408
f497e0a9 409 class Meta:
27b0b59f 410 db_table = 'account_profiles'
b7bdbc35 411 unique_together = (('uid', 'pid'),)
f497e0a9 412
27b0b59f
NI
413 def __str__(self):
414 return '%s -> %s' % (self.account.hruid, self.profile.hrpid)
f497e0a9
NI
415
416
417# Account-related
418# ===============
419
420
27b0b59f 421@python_2_unicode_compatible
f497e0a9
NI
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)
b7bdbc35 426
f497e0a9 427 class Meta:
27b0b59f 428 db_table = 'account_auth_openid'
f497e0a9 429
27b0b59f
NI
430 def __str__(self):
431 return "%s at %s" % (self.account, self.url)
f497e0a9 432
27b0b59f 433@python_2_unicode_compatible
f497e0a9
NI
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)
b7bdbc35 438
f497e0a9 439 class Meta:
27b0b59f 440 db_table = 'account_lost_passwords'
f497e0a9 441
27b0b59f
NI
442 def __str__(self):
443 return "%s on %s" % (self.account.hruid, self.created)
f497e0a9
NI
444
445
27b0b59f 446@python_2_unicode_compatible
f497e0a9
NI
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)
b7bdbc35 451
f497e0a9 452 class Meta:
27b0b59f 453 db_table = 'account_xnet_lost_passwords'
f497e0a9 454
27b0b59f
NI
455 def __str__(self):
456 return "%s on %s" % (self.account.hruid, self.date)
f497e0a9
NI
457
458
459# Announces
460# =========
461
462
27b0b59f 463@python_2_unicode_compatible
f497e0a9
NI
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,
b7bdbc35
NI
476 help_text="NNTP post identifier")
477
f497e0a9 478 class Meta:
27b0b59f 479 db_table = 'announces'
f497e0a9 480
27b0b59f
NI
481 def __str__(self):
482 return "%s: %s" % (self.id, self.titre)
f497e0a9
NI
483
484
27b0b59f 485@python_2_unicode_compatible
f497e0a9
NI
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()
b7bdbc35 492
f497e0a9 493 class Meta:
27b0b59f 494 db_table = 'announce_photos'
f497e0a9 495
27b0b59f
NI
496 def __str__(self):
497 return "%s (%s, %d x %d)" % (self.eid, self.attachmime, self.x, self.y)
f497e0a9
NI
498
499
27b0b59f 500@python_2_unicode_compatible
f497e0a9
NI
501class AnnounceRead(models.Model):
502 evt = models.ForeignKey(Announce)
503 account = models.ForeignKey(Account, db_column='uid')
b7bdbc35 504
f497e0a9 505 class Meta:
27b0b59f 506 db_table = 'announce_read'
b7bdbc35 507 unique_together = (('evt', 'uid'),)
f497e0a9 508
27b0b59f
NI
509 def __str__(self):
510 return "%s: %s" % (self.account, self.evt)
f497e0a9
NI
511
512
513# Email routing
514# =============
515
516
27b0b59f 517@python_2_unicode_compatible
f497e0a9
NI
518class EmailVirtual(models.Model):
519 email = models.CharField(max_length=255)
520 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
f497e0a9
NI
521 redirect = models.CharField(max_length=765)
522 type = models.CharField(max_length=21, blank=True)
523 expire = models.DateField()
b7bdbc35 524
f497e0a9 525 class Meta:
27b0b59f 526 db_table = 'email_virtual'
b7bdbc35 527 unique_together = (('email', 'domain'),)
f497e0a9 528
27b0b59f
NI
529 def __str__(self):
530 return "%s@%s (%s)" % (self.email, self.domain, self.type)
f497e0a9
NI
531
532
27b0b59f 533@python_2_unicode_compatible
f497e0a9
NI
534class EmailRedirectAccount(models.Model):
535 account = models.ForeignKey(Account, db_column='uid')
536 redirect = models.CharField(max_length=765)
f497e0a9
NI
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()
b7bdbc35 546
f497e0a9 547 class Meta:
27b0b59f 548 db_table = 'email_redirect_account'
b7bdbc35 549 unique_together = (('uid', 'redirect'),)
f497e0a9 550
27b0b59f
NI
551 def __str__(self):
552 return "%s for %s (%s)" % (self.redirect, self.account.hruid, self.type)
f497e0a9
NI
553
554
27b0b59f 555@python_2_unicode_compatible
f497e0a9
NI
556class EmailSourceAccount(models.Model):
557 email = models.CharField(max_length=255)
558 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
f497e0a9 559 account = models.ForeignKey(Account, db_column='uid')
07d99dd1
NI
560 type = models.CharField(max_length=9)
561 flags = models.CharField(max_length=23)
562 expire = models.DateField(blank=True, null=True)
563
f497e0a9 564 class Meta:
27b0b59f 565 db_table = 'email_source_account'
07d99dd1 566 unique_together = (('email', 'domain'),)
f497e0a9 567
27b0b59f
NI
568 def __str__(self):
569 return "%s@%s (%s)" % (self.email, self.domain, self.type)
f497e0a9
NI
570
571
27b0b59f 572@python_2_unicode_compatible
f497e0a9
NI
573class EmailSourceOther(models.Model):
574 email = models.CharField(max_length=255)
575 domain = models.ForeignKey(EmailVirtualDomain, db_column='domain')
07d99dd1
NI
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)
f497e0a9 579
f497e0a9 580 class Meta:
27b0b59f 581 db_table = 'email_source_other'
07d99dd1 582 unique_together = (('email', 'domain'),)
f497e0a9 583
27b0b59f
NI
584 def __str__(self):
585 return "%s@%s (%s)" % (self.email, self.domain, self.type)
f497e0a9
NI
586
587
27b0b59f 588@python_2_unicode_compatible
f497e0a9
NI
589class EmailRedirectOther(models.Model):
590 hrmid = models.ForeignKey(EmailSourceOther, db_column='hrmid')
07d99dd1
NI
591 redirect = models.CharField(max_length=255)
592 type = models.CharField(max_length=10)
593 action = models.CharField(max_length=18)
594
f497e0a9 595 class Meta:
27b0b59f 596 db_table = 'email_redirect_other'
07d99dd1 597 unique_together = (('hrmid', 'redirect'),)
f497e0a9 598
27b0b59f
NI
599 def __str__(self):
600 return "%s -> %s (%s)" % (self.hrmid, self.redirect, self.type)
f497e0a9
NI
601
602
603# innd-related
604# ============
605
606
27b0b59f 607@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 618
f497e0a9 619 class Meta:
27b0b59f 620 db_table = 'forum_innd'
f497e0a9 621
27b0b59f 622 def __str__(self):
f497e0a9
NI
623 return "%d: %s" % (self.id_innd, self.account.hruid)
624
625
27b0b59f 626@python_2_unicode_compatible
f497e0a9
NI
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()
07d99dd1 636
f497e0a9 637 class Meta:
27b0b59f 638 db_table = 'forum_profiles'
f497e0a9 639
27b0b59f
NI
640 def __str__(self):
641 return "%s: %s" % (self.account.hruid, self.name)
f497e0a9
NI
642
643
27b0b59f 644@python_2_unicode_compatible
f497e0a9
NI
645class Forum(models.Model):
646 fid = models.IntegerField(primary_key=True)
647 name = models.CharField(max_length=192)
07d99dd1 648
f497e0a9 649 class Meta:
27b0b59f 650 db_table = 'forums'
f497e0a9 651
27b0b59f 652 def __str__(self):
f497e0a9
NI
653 return self.name
654
655
27b0b59f 656@python_2_unicode_compatible
f497e0a9
NI
657class ForumSubs(models.Model):
658 forum = models.ForeignKey(Forum, db_column='fid')
659 account = models.ForeignKey(Account, db_column='uid')
07d99dd1 660
f497e0a9 661 class Meta:
27b0b59f 662 db_table = 'forum_subs'
07d99dd1 663 unique_together = (('fid', 'uid'),)
f497e0a9 664
27b0b59f
NI
665 def __str__(self):
666 return "%s by %s" % (self.forum.name, self.account.hruid)
f497e0a9
NI
667
668
669# Payments
670# ========
671
672
27b0b59f 673@python_2_unicode_compatible
f497e0a9 674class PaymentBankAccount(models.Model):
07d99dd1 675 id = models.IntegerField(primary_key=True)
f497e0a9
NI
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)
07d99dd1 681
f497e0a9 682 class Meta:
27b0b59f 683 db_table = 'payment_bankaccounts'
f497e0a9 684
27b0b59f
NI
685 def __str__(self):
686 return '%s: %s' % (self.asso.name, self.account)
f497e0a9
NI
687
688
27b0b59f 689@python_2_unicode_compatible
f497e0a9 690class Payment(models.Model):
07d99dd1 691 id = models.IntegerField(primary_key=True)
f497e0a9
NI
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)
07d99dd1 702
f497e0a9 703 class Meta:
27b0b59f 704 db_table = 'payments'
f497e0a9 705
27b0b59f
NI
706 def __str__(self):
707 return "%s: %s" % (self.id, self.text)
f497e0a9
NI
708
709
27b0b59f 710@python_2_unicode_compatible
f497e0a9
NI
711class PaymentCodeC(models.Model):
712 id = models.IntegerField(primary_key=True)
713 text = models.CharField(max_length=192)
07d99dd1 714
f497e0a9 715 class Meta:
27b0b59f 716 db_table = 'payment_codeC'
f497e0a9 717
27b0b59f 718 def __str__(self):
f497e0a9
NI
719 return self.text
720
721
27b0b59f 722@python_2_unicode_compatible
f497e0a9
NI
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.
07d99dd1 727
f497e0a9 728 class Meta:
27b0b59f 729 db_table = 'payment_codeRCB'
f497e0a9 730
27b0b59f 731 def __str__(self):
f497e0a9
NI
732 return self.text
733
734
27b0b59f 735@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 742
f497e0a9 743 class Meta:
27b0b59f 744 db_table = 'payment_methods'
f497e0a9 745
27b0b59f 746 def __str__(self):
f497e0a9
NI
747 return self.short_name
748
749
27b0b59f 750@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 762
f497e0a9 763 class Meta:
27b0b59f 764 db_table = 'payment_reconcilations'
f497e0a9 765
27b0b59f
NI
766 def __str__(self):
767 return "%s: %s" % (self.method, self.status)
f497e0a9
NI
768
769
27b0b59f 770@python_2_unicode_compatible
f497e0a9
NI
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()
07d99dd1 786
f497e0a9 787 class Meta:
27b0b59f 788 db_table = 'payment_transactions'
f497e0a9 789
27b0b59f
NI
790 def __str__(self):
791 return "%s (%s)" % (self.fullref, self.ref)
f497e0a9
NI
792
793
27b0b59f 794@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 803
f497e0a9 804 class Meta:
27b0b59f 805 db_table = 'payment_transfers'
f497e0a9 806
27b0b59f
NI
807 def __str__(self):
808 return "%s: %s" % (self.id, self.amount)
f497e0a9
NI
809
810
811# Groups
812# ======
813
814
27b0b59f 815@python_2_unicode_compatible
f497e0a9 816class GroupDom(models.Model):
07d99dd1 817 id = models.IntegerField(primary_key=True)
f497e0a9
NI
818 name = models.TextField(db_column='nom')
819 cat = models.CharField(max_length=117)
07d99dd1 820
f497e0a9 821 class Meta:
27b0b59f 822 db_table = 'group_dom'
f497e0a9 823
27b0b59f
NI
824 def __str__(self):
825 return "%s :: %s" % (self.cat, self.name)
f497e0a9
NI
826
827
27b0b59f 828@python_2_unicode_compatible
f497e0a9 829class Group(models.Model):
07d99dd1 830 id = models.IntegerField(primary_key=True)
f497e0a9
NI
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)
07d99dd1 854
f497e0a9 855 class Meta:
27b0b59f 856 db_table = 'groups'
f497e0a9 857
27b0b59f 858 def __str__(self):
f497e0a9
NI
859 return self.name
860
861
862# Group::membership
863# -----------------
864
865
27b0b59f 866@python_2_unicode_compatible
f497e0a9
NI
867class GroupMember(models.Model):
868 asso = models.ForeignKey(Group)
869 account = models.ForeignKey(Account, db_column='uid')
07d99dd1
NI
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)
f497e0a9 874
f497e0a9 875 class Meta:
27b0b59f 876 db_table = 'group_members'
07d99dd1 877 unique_together = (('asso', 'uid'),)
f497e0a9 878
27b0b59f
NI
879 def __str__(self):
880 return "%s to %s" % (self.account.hruid, self.asso.name)
f497e0a9
NI
881
882
27b0b59f 883@python_2_unicode_compatible
f497e0a9
NI
884class GroupMemberSubRequest(models.Model):
885 asso = models.ForeignKey(Group)
886 account = models.ForeignKey(Account, db_column='uid')
f497e0a9
NI
887 ts = models.DateTimeField()
888 reason = models.TextField(blank=True)
07d99dd1 889
f497e0a9 890 class Meta:
27b0b59f 891 db_table = 'group_member_sub_requests'
07d99dd1 892 unique_together = (('asso', 'uid'),)
f497e0a9 893
27b0b59f
NI
894 def __str__(self):
895 return "%s to %s" % (self.account.hruid, self.asso.name)
f497e0a9
NI
896
897
27b0b59f 898@python_2_unicode_compatible
f497e0a9
NI
899class GroupFormerMember(models.Model):
900 asso = models.ForeignKey(Group)
901 account = models.ForeignKey(Account, db_column='uid')
f497e0a9
NI
902 remember = models.IntegerField()
903 unsubsciption_date = models.DateField()
07d99dd1 904
f497e0a9 905 class Meta:
27b0b59f 906 db_table = 'group_former_members'
07d99dd1 907 unique_together = (('asso', 'uid'),)
f497e0a9 908
27b0b59f
NI
909 def __str__(self):
910 return "%s to %s" % (self.account.hruid, self.asso.name)
f497e0a9
NI
911
912
913# Group::Announces
914# ----------------
915
916
27b0b59f 917@python_2_unicode_compatible
f497e0a9
NI
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,
07d99dd1
NI
931 help_text="NNTP post ID")
932
f497e0a9 933 class Meta:
27b0b59f 934 db_table = 'group_announces'
f497e0a9 935
27b0b59f
NI
936 def __str__(self):
937 return "%s: %s" % (self.asso.name, self.titre)
f497e0a9
NI
938
939
27b0b59f 940@python_2_unicode_compatible
f497e0a9
NI
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()
07d99dd1 947
f497e0a9 948 class Meta:
27b0b59f 949 db_table = 'group_announces_photo'
f497e0a9 950
27b0b59f
NI
951 def __str__(self):
952 return "%s (%s, %d x %d)" % (self.eid, self.attachmime, self.x, self.y)
f497e0a9
NI
953
954
27b0b59f 955@python_2_unicode_compatible
f497e0a9
NI
956class GroupAnnounceRead(models.Model):
957 announce = models.ForeignKey(GroupAnnounce)
958 account = models.ForeignKey(Account, db_column='uid')
07d99dd1 959
f497e0a9 960 class Meta:
27b0b59f 961 db_table = 'group_announces_read'
07d99dd1 962 unique_together = (('announce', 'uid'),)
f497e0a9 963
27b0b59f
NI
964 def __str__(self):
965 return "%s: %s" % (self.account.hruid, self.announce_id)
f497e0a9
NI
966
967
968# Group::Event
969# ------------
970
971
27b0b59f 972@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 989
f497e0a9 990 class Meta:
27b0b59f 991 db_table = 'group_events'
f497e0a9 992
27b0b59f
NI
993 def __str__(self):
994 return "%s: %s" % (self.asso.name, self.intitule)
f497e0a9
NI
995
996
27b0b59f 997@python_2_unicode_compatible
f497e0a9
NI
998class GroupEventItem(models.Model):
999 event = models.ForeignKey(GroupEvent, db_column='eid')
1000 item_id = models.IntegerField()
f497e0a9
NI
1001 titre = models.CharField(max_length=300)
1002 details = models.TextField()
1003 montant = models.DecimalField(max_digits=12, decimal_places=2)
07d99dd1 1004
f497e0a9 1005 class Meta:
27b0b59f 1006 db_table = 'group_event_items'
07d99dd1 1007 unique_together = (('eid', 'item_id'),)
f497e0a9 1008
27b0b59f
NI
1009 def __str__(self):
1010 return "%s - %s" % (self.event, self.item_id)
f497e0a9
NI
1011
1012
27b0b59f 1013@python_2_unicode_compatible
f497e0a9
NI
1014class GroupEventParticipant(models.Model):
1015 event = models.ForeignKey(GroupEvent, db_column='eid')
f497e0a9
NI
1016 account = models.ForeignKey(Account, db_column='uid')
1017 item = models.ForeignKey(GroupEventItem, to_field='pkey')
f497e0a9 1018 nb = models.IntegerField()
07d99dd1 1019 flags = models.CharField(max_length=14)
f497e0a9 1020 paid = models.FloatField()
07d99dd1
NI
1021
1022
f497e0a9 1023 class Meta:
27b0b59f 1024 db_table = 'group_event_participants'
07d99dd1 1025 unique_together = (('eid', 'uid', 'item_id'),)
f497e0a9 1026
27b0b59f
NI
1027 def __str__(self):
1028 return "%s to %s" % (self.account.hruid, self.item)
f497e0a9
NI
1029
1030
1031# Group::misc
1032# -----------
1033
1034
27b0b59f 1035@python_2_unicode_compatible
f497e0a9
NI
1036class GroupAuth(models.Model):
1037 #id = models.IntegerField(primary_key=True)
1038 privkey = models.CharField(max_length=120, unique=True)
1039 name = models.CharField(max_length=96)
1040 datafields = models.CharField(max_length=765)
1041 returnurls = models.CharField(max_length=765)
1042 last_used = models.DateField(null=True, blank=True)
1043 group = models.ForeignKey(Group, null=True, blank=True)
1044 flags = models.CharField(max_length=63, blank=True)
07d99dd1 1045
f497e0a9 1046 class Meta:
27b0b59f 1047 db_table = 'group_auth'
f497e0a9 1048
27b0b59f 1049 def __str__(self):
f497e0a9
NI
1050 return self.name
1051
1052
1053# Logging
1054# =======
1055
1056
27b0b59f 1057@python_2_unicode_compatible
f497e0a9
NI
1058class IpWatch(models.Model):
1059 state = models.CharField(max_length=27)
1060 detection = models.DateField(null=True, blank=True)
1061 last = models.DateTimeField()
1062 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
1063 description = models.TextField()
1064 ip = models.IntegerField(primary_key=True)
1065 mask = models.IntegerField()
07d99dd1 1066
f497e0a9 1067 class Meta:
27b0b59f 1068 db_table = 'ip_watch'
f497e0a9 1069
27b0b59f 1070 def __str__(self):
f497e0a9
NI
1071 return self.ip
1072
1073
27b0b59f 1074@python_2_unicode_compatible
f497e0a9 1075class LogAction(models.Model):
07d99dd1 1076 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1077 text = models.CharField(max_length=96)
1078 description = models.CharField(max_length=765)
07d99dd1 1079
f497e0a9 1080 class Meta:
27b0b59f 1081 db_table = 'log_actions'
f497e0a9 1082
27b0b59f 1083 def __str__(self):
f497e0a9
NI
1084 return self.text
1085
1086
27b0b59f 1087@python_2_unicode_compatible
f497e0a9 1088class LogSession(models.Model):
07d99dd1 1089 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1090 auth = models.CharField(max_length=18)
1091 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True, related_name='sessions')
1092 start = models.DateTimeField()
1093 host = models.CharField(max_length=384)
1094 sauth = models.CharField(max_length=18)
1095 suid = models.ForeignKey(Account, null=True, db_column='suid', blank=True, related_name='su_sessions')
1096 browser = models.CharField(max_length=765)
1097 forward_host = models.CharField(max_length=384, blank=True)
1098 flags = models.CharField(max_length=15)
1099 ip = models.IntegerField()
1100 forward_ip = models.IntegerField(null=True, blank=True)
07d99dd1 1101
f497e0a9 1102 class Meta:
27b0b59f 1103 db_table = 'log_sessions'
f497e0a9 1104
27b0b59f
NI
1105 def __str__(self):
1106 return "%s: %s@%s" % (self.id, self.account.hruid, self.host)
f497e0a9
NI
1107
1108
27b0b59f 1109@python_2_unicode_compatible
f497e0a9
NI
1110class LogLastSession(models.Model):
1111 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
1112 id = models.ForeignKey(LogSession, db_column='id')
07d99dd1 1113
f497e0a9 1114 class Meta:
27b0b59f 1115 db_table = 'log_last_sessions'
f497e0a9 1116
27b0b59f 1117 def __str__(self):
f497e0a9
NI
1118 return self.account.hruid
1119
1120
27b0b59f 1121@python_2_unicode_compatible
f497e0a9
NI
1122class LogEvent(models.Model):
1123 stamp = models.DateTimeField(primary_key=True)
1124 session = models.ForeignKey(LogSession, db_column='session')
1125 action = models.ForeignKey(LogAction, db_column='action')
1126 data = models.TextField(blank=True)
07d99dd1 1127
f497e0a9 1128 class Meta:
27b0b59f 1129 db_table = 'log_events'
f497e0a9 1130
27b0b59f
NI
1131 def __str__(self):
1132 return "%s@%s: %s" % (self.session_id, self.stamp, self.action.text)
f497e0a9
NI
1133
1134
1135# Newsletters
1136# ===========
1137
1138
27b0b59f 1139@python_2_unicode_compatible
f497e0a9
NI
1140class Newsletter(models.Model):
1141 #id = models.IntegerField(primary_key=True)
1142 group = models.ForeignKey(Group, unique=True)
1143 name = models.CharField(max_length=765)
1144 criteria = models.CharField(max_length=42, blank=True)
07d99dd1 1145
f497e0a9 1146 class Meta:
27b0b59f 1147 db_table = 'newsletters'
f497e0a9 1148
27b0b59f 1149 def __str__(self):
f497e0a9
NI
1150 return self.name
1151
1152
27b0b59f 1153@python_2_unicode_compatible
f497e0a9
NI
1154class NewsletterIssue(models.Model):
1155 nlid = models.ForeignKey(Newsletter, unique=True, db_column='nlid')
07d99dd1 1156 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1157 date = models.DateField()
1158 send_before = models.DateTimeField(null=True, blank=True)
1159 state = models.CharField(max_length=21)
1160 sufb_json = models.TextField(blank=True)
1161 title = models.CharField(max_length=765)
1162 head = models.TextField()
1163 signature = models.TextField()
1164 short_name = models.CharField(max_length=48, unique=True, blank=True)
1165 mail_title = models.CharField(max_length=765)
1166 unsubscribe = models.IntegerField()
1167 reply_to = models.CharField(max_length=765)
07d99dd1 1168
f497e0a9 1169 class Meta:
27b0b59f 1170 db_table = 'newsletter_issues'
f497e0a9 1171
27b0b59f 1172 def __str__(self):
f497e0a9
NI
1173 return self.title
1174
1175
27b0b59f 1176@python_2_unicode_compatible
f497e0a9
NI
1177class NewsletterCat(models.Model):
1178 cid = models.AutoField(primary_key=True)
1179 nlid = models.ForeignKey(Newsletter, db_column='nlid')
1180 pos = models.IntegerField()
1181 title = models.CharField(max_length=384)
07d99dd1 1182
f497e0a9 1183 class Meta:
27b0b59f 1184 db_table = 'newsletter_cat'
f497e0a9 1185
27b0b59f 1186 def __str__(self):
f497e0a9
NI
1187 return self.title
1188
1189
27b0b59f 1190@python_2_unicode_compatible
f497e0a9
NI
1191class NewsletterArt(models.Model):
1192 issue = models.ForeignKey(NewsletterIssue, db_column='id')
1193 aid = models.IntegerField()
f497e0a9
NI
1194 cid = models.ForeignKey(NewsletterCat, null=True, db_column='cid', blank=True)
1195 pos = models.IntegerField()
1196 title = models.TextField()
1197 body = models.TextField()
1198 append = models.TextField()
07d99dd1 1199
f497e0a9 1200 class Meta:
27b0b59f 1201 db_table = 'newsletter_art'
07d99dd1 1202 unique_together = (('issue', 'aid'),)
f497e0a9 1203
27b0b59f
NI
1204 def __str__(self):
1205 return "%s: %s" % (self.issue_id, self.title)
f497e0a9
NI
1206
1207
27b0b59f 1208@python_2_unicode_compatible
f497e0a9
NI
1209class NewsletterIns(models.Model):
1210 account = models.ForeignKey(Account, db_column='uid')
1211 nl = models.ForeignKey(Newsletter, db_column='nlid')
f497e0a9
NI
1212 last = models.ForeignKey(NewsletterIssue, null=True, db_column='last', blank=True)
1213 hash = models.CharField(max_length=96, blank=True)
07d99dd1 1214
f497e0a9 1215 class Meta:
27b0b59f 1216 db_table = 'newsletter_ins'
07d99dd1 1217 unique_together = (('uid', 'nlid'),)
f497e0a9 1218
27b0b59f
NI
1219 def __str__(self):
1220 return "%s to %s" % (self.account.hruid, self.nl.title)
f497e0a9
NI
1221
1222
1223# Profile
1224# =======
1225
1226
27b0b59f 1227@python_2_unicode_compatible
f497e0a9
NI
1228class ProfileDisplay(models.Model):
1229 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1230 yourself = models.CharField(max_length=765)
1231 public_name = models.CharField(max_length=765)
1232 private_name = models.CharField(max_length=765)
1233 directory_name = models.CharField(max_length=765)
1234 short_name = models.CharField(max_length=765)
1235 sort_name = models.CharField(max_length=765)
1236 promo = models.CharField(max_length=765)
07d99dd1 1237
f497e0a9 1238 class Meta:
27b0b59f 1239 db_table = 'profile_display'
f497e0a9 1240
27b0b59f 1241 def __str__(self):
f497e0a9
NI
1242 return self.profile.hrpid
1243
1244
27b0b59f 1245@python_2_unicode_compatible
f497e0a9
NI
1246class ProfilePhone(models.Model):
1247 LINK_ADDRESS = 'address'
1248 LINK_PRO = 'pro'
1249 LINK_USER = 'user'
1250 LINK_HQ = 'hq'
1251 LINK_GROUP = 'group'
1252 LINK_CHOICES = (
1253 (LINK_ADDRESS, u"Address"),
1254 (LINK_PRO, u"Pro"),
1255 (LINK_USER, u"User"),
1256 (LINK_HQ, u"HQ"),
1257 (LINK_GROUP, u"Group"),
1258 )
1259
1260 KIND_FIXED = 'fixed'
1261 KIND_MOBILE = 'mobile'
1262 KIND_FAX = 'fax'
1263 KIND_CHOICES = (
1264 (KIND_FIXED, u"Fixed"),
1265 (KIND_MOBILE, u"Mobile"),
1266 (KIND_FAX, u"Fax"),
1267 )
1268
1269 profile = models.ForeignKey(Profile, db_column='pid', related_name='phones')
1270 link_type = models.CharField(max_length=21, choices=LINK_CHOICES)
1271 link_id = models.IntegerField()
1272 tel_id = models.IntegerField()
f497e0a9
NI
1273 tel_type = models.CharField(max_length=18, choices=KIND_CHOICES)
1274 search_tel = models.CharField(max_length=75)
1275 display_tel = models.CharField(max_length=90)
1276 pub = models.CharField(max_length=21)
1277 comment = models.CharField(max_length=240)
1278
1279 class Meta:
27b0b59f 1280 db_table = 'profile_phones'
07d99dd1 1281 unique_together = (('pid', 'link_type', 'link_id', 'tel_id'),)
f497e0a9 1282
27b0b59f
NI
1283 def __str__(self):
1284 return "%s: %s (%s)" % (self.profile.hrpid, self.display_tel, self.tel_type)
f497e0a9
NI
1285
1286 @property
1287 def is_address(self):
1288 return self.link_type == self.LINK_ADDRESS
1289
1290 @property
1291 def is_job(self):
1292 return self.link_type == self.LINK_PRO
1293
1294 @property
1295 def ax_visible(self):
1296 return is_ax_visible(self.pub)
1297
1298
27b0b59f 1299@python_2_unicode_compatible
f497e0a9
NI
1300class ProfilePhoto(models.Model):
1301 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid', related_name='photo')
1302 attachmime = models.CharField(max_length=12)
1303 attach = models.TextField()
1304 x = models.IntegerField()
1305 y = models.IntegerField()
1306 pub = models.CharField(max_length=21)
1307 last_update = models.DateTimeField()
07d99dd1 1308
f497e0a9 1309 class Meta:
27b0b59f 1310 db_table = 'profile_photos'
f497e0a9 1311
27b0b59f 1312 def __str__(self):
f497e0a9
NI
1313 return self.profile.hrpid
1314
1315
27b0b59f 1316@python_2_unicode_compatible
f497e0a9
NI
1317class ProfilePrivateName(models.Model):
1318 profile = models.ForeignKey(Profile, db_column='pid', related_name='private_name')
1319 type = models.CharField(max_length=27)
1320 id = models.IntegerField()
f497e0a9 1321 name = models.CharField(max_length=765)
07d99dd1 1322
f497e0a9 1323 class Meta:
27b0b59f 1324 db_table = 'profile_private_names'
07d99dd1 1325 unique_together = (('pid', 'type', 'id'),)
f497e0a9 1326
27b0b59f
NI
1327 def __str__(self):
1328 return "%s: %s" % (self.profile.hrpid, self.type)
f497e0a9
NI
1329
1330
27b0b59f 1331@python_2_unicode_compatible
f497e0a9
NI
1332class ProfilePublicName(models.Model):
1333 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid', related_name='public_name')
1334 lastname_initial = models.CharField(max_length=765)
1335 lastname_main = models.CharField(max_length=765)
1336 lastname_marital = models.CharField(max_length=765)
1337 lastname_ordinary = models.CharField(max_length=765)
1338 firstname_initial = models.CharField(max_length=765)
1339 firstname_main = models.CharField(max_length=765)
1340 firstname_ordinary = models.CharField(max_length=765)
1341 pseudonym = models.CharField(max_length=765)
07d99dd1 1342
f497e0a9 1343 class Meta:
27b0b59f 1344 db_table = 'profile_public_names'
f497e0a9 1345
27b0b59f 1346 def __str__(self):
f497e0a9
NI
1347 return self.profile.hrpid
1348
1349
1350# Profile::addresses
1351# ------------------
1352
1353
27b0b59f 1354@python_2_unicode_compatible
f497e0a9
NI
1355class ProfileAddress(models.Model):
1356
1357 KIND_HOME = 'home'
1358 KIND_HQ = 'hq'
1359 KIND_JOB = 'job'
1360 KIND_GROUP = 'group'
1361
1362 KIND_CHOICES = (
1363 (KIND_HOME, u"Home"),
1364 (KIND_HQ, u"Headquarters"),
1365 (KIND_JOB, u"Job"),
1366 (KIND_GROUP, u"Group"),
1367 )
1368
1369 profile = models.ForeignKey(Profile, db_column='pid', related_name='addresses')
1370 job = models.ForeignKey('ProfileJobEnum', db_column='jobid', blank=True, null=True,
07d99dd1 1371 related_name='addresses')
f497e0a9 1372 group = models.ForeignKey('Group', db_column='groupid', blank=True, null=True)
07d99dd1 1373 addr_type = models.CharField(max_length=5, db_column='type', choices=KIND_CHOICES)
f497e0a9 1374 subid = models.IntegerField(db_column='id')
07d99dd1 1375 flags = models.CharField(max_length=65, blank=True, null=True)
f497e0a9 1376 text = models.TextField()
07d99dd1 1377 postaltext = models.TextField(db_column='postalText') # Field name made lowercase.
f497e0a9 1378 formatted_address = models.TextField()
07d99dd1
NI
1379 types = models.CharField(max_length=297)
1380 latitude = models.FloatField(blank=True, null=True)
1381 longitude = models.FloatField(blank=True, null=True)
1382 southwest_latitude = models.FloatField(blank=True, null=True)
1383 southwest_longitude = models.FloatField(blank=True, null=True)
1384 northeast_latitude = models.FloatField(blank=True, null=True)
1385 northeast_longitude = models.FloatField(blank=True, null=True)
1386 location_type = models.CharField(max_length=18, blank=True, null=True)
f497e0a9 1387 partial_match = models.IntegerField()
07d99dd1
NI
1388 pub = models.CharField(max_length=7)
1389 comment = models.CharField(max_length=255, blank=True, null=True)
1390 geocoding_date = models.DateField(blank=True, null=True)
f497e0a9 1391 geocoding_calls = models.IntegerField()
07d99dd1 1392 postal_code_fr = models.CharField(max_length=5, blank=True, null=True)
f497e0a9
NI
1393 components = models.ManyToManyField('ProfileAddressComponentEnum',
1394 through='ProfileAddressComponent', related_name='addresses')
1395
1396 class Meta:
27b0b59f 1397 db_table = 'profile_addresses'
07d99dd1 1398 unique_together = (('pid', 'jobid', 'groupid', 'type', 'id'),)
f497e0a9 1399
27b0b59f 1400 def __str__(self):
f497e0a9
NI
1401 if self.addr_type == self.KIND_HOME:
1402 rel = self.profile.hrpid
1403 elif self.addr_type == self.KIND_HQ:
1404 if self.jobid:
1405 rel = unicode(self.job)
1406 else:
1407 rel = u"[BADJOB]"
1408 elif self.addr_type == self.KIND_GROUP:
1409 rel = unicode(self.group)
1410 else:
1411 rel = u"%s at %s" % (self.profile.hrpid, self.pjob.company)
27b0b59f 1412 return "%s address %d for %s" % (
f497e0a9
NI
1413 self.get_addr_type_display(), self.subid, rel)
1414
1415 @property
1416 def ax_visible(self):
1417 return is_ax_visible(self.pub)
1418
1419 def get_components_by_type(self):
1420 flags = collections.defaultdict(list)
1421 for component in self.components.all():
1422 for cp_type in component.types.split(','):
1423 flags[cp_type].append(component)
1424 return flags
1425
1426 @property
1427 def flag_list(self):
1428 return self.flags.split(',')
1429
1430 FLAG_CURRENT = 'current'
1431 FLAG_MAIL = 'mail'
1432 FLAG_SECONDARY = 'secondary'
1433
1434 @property
1435 def current(self):
1436 return self.FLAG_CURRENT in self.flag_list
1437
1438 @property
1439 def mail(self):
1440 return self.FLAG_MAIL in self.flag_list
1441
1442 @property
1443 def secondary(self):
1444 return self.FLAG_SECONDARY in self.flag_list
1445
1446 @property
1447 def is_home(self):
1448 return self.addr_type == self.KIND_HOME
1449
1450 @property
1451 def is_job(self):
1452 return self.addr_type == self.KIND_JOB
1453
1454
27b0b59f 1455@python_2_unicode_compatible
f497e0a9
NI
1456class ProfileAddressComponentEnum(models.Model):
1457 #id = models.BigIntegerField(primary_key=True)
1458 short_name = models.CharField(max_length=765)
1459 long_name = models.CharField(max_length=765)
1460 types = models.CharField(max_length=891)
07d99dd1 1461
f497e0a9 1462 class Meta:
27b0b59f 1463 db_table = 'profile_addresses_components_enum'
f497e0a9 1464
27b0b59f
NI
1465 def __str__(self):
1466 return '%s (%s)' % (self.short_name, self.types)
f497e0a9
NI
1467
1468
27b0b59f 1469@python_2_unicode_compatible
f497e0a9
NI
1470class ProfileAddressComponent(models.Model):
1471 profile = models.ForeignKey(Profile, db_column='pid')
1472 job = models.ForeignKey('ProfileJobEnum', db_column='jobid')
1473 group = models.ForeignKey(Group, db_column='groupid', blank=True, null=True)
1474 addr_type = models.CharField(max_length=15, db_column='type')
1475 subid = models.IntegerField(db_column='id')
f497e0a9
NI
1476
1477 component = models.ForeignKey(ProfileAddressComponentEnum, related_name='component_links')
07d99dd1
NI
1478 address = models.ForeignKey(ProfileAddress, related_name='component_links')
1479
f497e0a9 1480 class Meta:
27b0b59f 1481 db_table = 'profile_addresses_components'
07d99dd1 1482 unique_together = (('pid', 'jobid', 'groupid', 'type', 'id'),)
f497e0a9 1483
27b0b59f
NI
1484 def __str__(self):
1485 return "%s (%s) for %s" % (
f497e0a9
NI
1486 self.component.long_name,
1487 self.component.types,
1488 self.address,
1489 )
1490
1491
1492# Profile::networking
1493# -------------------
1494
1495
1496class ProfileBinetEnum(models.Model):
07d99dd1 1497 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1498 text = models.CharField(max_length=150)
1499 url = models.CharField(max_length=765)
07d99dd1 1500
f497e0a9 1501 class Meta:
27b0b59f 1502 db_table = 'profile_binet_enum'
f497e0a9
NI
1503
1504
1505class ProfileBinet(models.Model):
1506 profile = models.ForeignKey(Profile, db_column='pid')
1507 binet = models.ForeignKey(ProfileBinetEnum)
07d99dd1 1508
f497e0a9 1509 class Meta:
27b0b59f 1510 db_table = 'profile_binets'
07d99dd1 1511 unique_together = (('pid', 'binet'),)
f497e0a9
NI
1512
1513
1514class ProfileHobby(models.Model):
1515 profile = models.ForeignKey(Profile, db_column='pid')
1516 id = models.IntegerField()
f497e0a9
NI
1517 type = models.CharField(max_length=18)
1518 text = models.CharField(max_length=765)
1519 pub = models.CharField(max_length=21)
07d99dd1 1520
f497e0a9 1521 class Meta:
27b0b59f 1522 db_table = 'profile_hobby'
07d99dd1 1523 unique_together = (('pid', 'id'),)
f497e0a9
NI
1524
1525
1526class ProfileNetworkingEnum(models.Model):
1527 nwid = models.IntegerField(primary_key=True)
1528 name = models.CharField(max_length=90)
1529 icon = models.CharField(max_length=150)
1530 filter = models.CharField(max_length=18)
1531 network_type = models.CharField(max_length=18)
1532 link = models.CharField(max_length=765)
07d99dd1 1533
f497e0a9 1534 class Meta:
27b0b59f 1535 db_table = 'profile_networking_enum'
f497e0a9
NI
1536
1537
1538class ProfileNetworking(models.Model):
1539 profile = models.ForeignKey(Profile, db_column='pid')
1540 id = models.IntegerField()
1541 nwid = models.ForeignKey(ProfileNetworkingEnum, db_column='nwid')
f497e0a9
NI
1542 address = models.CharField(max_length=765)
1543 pub = models.CharField(max_length=21)
07d99dd1 1544
f497e0a9 1545 class Meta:
27b0b59f 1546 db_table = 'profile_networking'
07d99dd1 1547 unique_together = (('pid', 'nwid'),)
f497e0a9
NI
1548
1549
1550# Profile::corps
1551# --------------
1552
1553
27b0b59f 1554@python_2_unicode_compatible
f497e0a9 1555class ProfileCorpsEnum(models.Model):
07d99dd1 1556 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1557 name = models.CharField(max_length=255, unique=True)
1558 abbreviation = models.CharField(max_length=15, unique=True)
1559 still_exists = models.IntegerField()
07d99dd1 1560
f497e0a9 1561 class Meta:
27b0b59f 1562 db_table = 'profile_corps_enum'
f497e0a9 1563
27b0b59f 1564 def __str__(self):
f497e0a9
NI
1565 return self.name
1566
1567
27b0b59f 1568@python_2_unicode_compatible
f497e0a9 1569class ProfileCorpsRankEnum(models.Model):
07d99dd1 1570 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1571 name = models.CharField(max_length=255, unique=True)
1572 abbreviation = models.CharField(max_length=15, unique=True)
07d99dd1 1573
f497e0a9 1574 class Meta:
27b0b59f 1575 db_table = 'profile_corps_rank_enum'
f497e0a9 1576
27b0b59f 1577 def __str__(self):
f497e0a9
NI
1578 return self.name
1579
1580
27b0b59f 1581@python_2_unicode_compatible
f497e0a9
NI
1582class ProfileCorps(models.Model):
1583 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1584 original = models.ForeignKey(ProfileCorpsEnum, db_column='original_corpsid', related_name='original_members')
1585 current = models.ForeignKey(ProfileCorpsEnum, db_column='current_corpsid', related_name='current_members')
1586 rank = models.ForeignKey(ProfileCorpsRankEnum, db_column='rankid')
1587 # Ignored: corps is public information anyway.
1588 corps_pub = models.CharField(max_length=21)
07d99dd1 1589
f497e0a9 1590 class Meta:
27b0b59f 1591 db_table = 'profile_corps'
f497e0a9 1592
27b0b59f
NI
1593 def __str__(self):
1594 return "%s: %s" % (self.profile.hrpid, self.current.name)
f497e0a9
NI
1595
1596
1597# Profile::edu
1598# ------------
1599
1600
27b0b59f 1601@python_2_unicode_compatible
f497e0a9 1602class ProfileEducationEnum(models.Model):
07d99dd1 1603 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1604 name = models.CharField(max_length=255, unique=True, blank=True)
1605 abbreviation = models.CharField(max_length=765)
1606 url = models.CharField(max_length=765, blank=True)
1607 country = models.ForeignKey(GeolocCountry, null=True, db_column='country', blank=True)
1608 class Meta:
27b0b59f 1609 db_table = 'profile_education_enum'
f497e0a9 1610
27b0b59f 1611 def __str__(self):
f497e0a9
NI
1612 return self.name
1613
1614 @property
1615 def short(self):
1616 return self.abbreviation or self.name
1617
1618
27b0b59f 1619@python_2_unicode_compatible
f497e0a9 1620class ProfileEducationDegreeEnum(models.Model):
07d99dd1 1621 id = models.IntegerField(primary_key=True)
f497e0a9
NI
1622 degree = models.CharField(max_length=255, unique=True, blank=True)
1623 abbreviation = models.CharField(max_length=765)
1624 level = models.IntegerField()
07d99dd1 1625
f497e0a9 1626 class Meta:
27b0b59f 1627 db_table = 'profile_education_degree_enum'
f497e0a9 1628
27b0b59f 1629 def __str__(self):
f497e0a9
NI
1630 return self.degree
1631
1632
27b0b59f 1633@python_2_unicode_compatible
f497e0a9 1634class ProfileEducationFieldEnum(models.Model):
07d99dd1 1635 id = models.IntegerField(primary_key=True)
f497e0a9 1636 field = models.CharField(max_length=255, unique=True, blank=True)
07d99dd1 1637
f497e0a9 1638 class Meta:
27b0b59f 1639 db_table = 'profile_education_field_enum'
f497e0a9 1640
27b0b59f 1641 def __str__(self):
f497e0a9
NI
1642 return self.field
1643
1644
27b0b59f 1645@python_2_unicode_compatible
f497e0a9
NI
1646class ProfileEducation(models.Model):
1647 id = models.IntegerField()
1648 profile = models.ForeignKey(Profile, db_column='pid', related_name='educations')
f497e0a9
NI
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)
07d99dd1 1657
f497e0a9 1658 class Meta:
27b0b59f 1659 db_table = 'profile_education'
07d99dd1 1660 unique_together = (('id', 'pid'),)
f497e0a9 1661
27b0b59f
NI
1662 def __str__(self):
1663 return "%s: %s" % (self.profile.hrpid, self.edu.name)
f497e0a9
NI
1664
1665
27b0b59f 1666@python_2_unicode_compatible
f497e0a9
NI
1667class ProfileEducationDegree(models.Model):
1668 edu = models.ForeignKey(ProfileEducationEnum, db_column='eduid')
1669 degree = models.ForeignKey(ProfileEducationDegreeEnum, db_column='degreeid')
07d99dd1 1670
f497e0a9 1671 class Meta:
27b0b59f 1672 db_table = 'profile_education_degree'
07d99dd1 1673 unique_together = (('eduid', 'degreeid'),)
f497e0a9 1674
27b0b59f
NI
1675 def __str__(self):
1676 return "%s - %s" % (self.edu, self.degree)
f497e0a9
NI
1677
1678
1679# Profile::jobs
1680# -------------
1681
1682
27b0b59f 1683@python_2_unicode_compatible
f497e0a9 1684class ProfileJobEnum(models.Model):
07d99dd1 1685 id = models.IntegerField(primary_key=True)
f497e0a9
NI
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.
07d99dd1 1694
f497e0a9 1695 class Meta:
27b0b59f 1696 db_table = 'profile_job_enum'
f497e0a9 1697
27b0b59f 1698 def __str__(self):
f497e0a9
NI
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
27b0b59f 1713@python_2_unicode_compatible
f497e0a9
NI
1714class ProfileJob(models.Model):
1715 id = models.IntegerField()
1716 profile = models.ForeignKey(Profile, db_column='pid', related_name='jobs')
f497e0a9
NI
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)
07d99dd1 1724
f497e0a9 1725 class Meta:
27b0b59f 1726 db_table = 'profile_job'
07d99dd1 1727 unique_together = (('pid', 'id'),)
f497e0a9
NI
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
27b0b59f
NI
1737 def __str__(self):
1738 return "%s at %s" % (self.profile.hrpid, self.company.name if self.company else '<NONE>')
f497e0a9
NI
1739
1740
1741# Profile::job::terms
1742# -------------------
1743
1744
27b0b59f 1745@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 1750
f497e0a9 1751 class Meta:
27b0b59f 1752 db_table = 'profile_job_term_enum'
f497e0a9 1753
27b0b59f 1754 def __str__(self):
f497e0a9
NI
1755 return self.name
1756
1757
27b0b59f 1758@python_2_unicode_compatible
f497e0a9
NI
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)
07d99dd1 1764
f497e0a9 1765 class Meta:
27b0b59f 1766 db_table = 'profile_job_term_relation'
07d99dd1 1767 unique_together = (('jtid_1', 'jtid_2', 'computed'),)
f497e0a9 1768
27b0b59f
NI
1769 def __str__(self):
1770 return "%s <-> %s" % (self.jtid_1.name, self.jtid_2.name)
f497e0a9
NI
1771
1772
27b0b59f 1773@python_2_unicode_compatible
f497e0a9
NI
1774class ProfileJobTermSearch(models.Model):
1775 search = models.CharField(max_length=150)
1776 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
07d99dd1 1777
f497e0a9 1778 class Meta:
27b0b59f 1779 db_table = 'profile_job_term_search'
07d99dd1 1780 unique_together = (('search', 'job_term'),)
f497e0a9 1781
27b0b59f
NI
1782 def __str__(self):
1783 return "%s => %s" % (self.search, self.job_term.name)
f497e0a9
NI
1784
1785
27b0b59f 1786@python_2_unicode_compatible
f497e0a9
NI
1787class ProfileJobTerm(models.Model):
1788 profile = models.ForeignKey(Profile, db_column='pid')
1789 company = models.ForeignKey(ProfileJobEnum, db_column='jid')
1790 job = models.ForeignKey(ProfileJob, to_field='pkey')
1791 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1792 computed = models.CharField(max_length=24)
1793 pkey = models.CompositeField(profile, company, job_term, primary_key=True)
1794 class Meta:
27b0b59f 1795 db_table = 'profile_job_term'
f497e0a9 1796
27b0b59f
NI
1797 def __str__(self):
1798 return "%s at %s: %s" % (self.profile.hrpid, self.company.name, self.job_term.name)
f497e0a9
NI
1799
1800
27b0b59f 1801@python_2_unicode_compatible
f497e0a9
NI
1802class ProfileJobEntrepriseTerm(models.Model):
1803 job = models.ForeignKey(ProfileJobEnum, db_column='eid')
1804 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1805 pkey = models.CompositeField(job, job_term, primary_key=True)
1806 class Meta:
27b0b59f 1807 db_table = 'profile_job_entreprise_term'
f497e0a9 1808
27b0b59f
NI
1809 def __str__(self):
1810 return "%s: %s" % (self.job.name, self.job_term.name)
f497e0a9
NI
1811
1812
1813# Profile::skills
1814# ---------------
1815
1816
27b0b59f 1817@python_2_unicode_compatible
f497e0a9
NI
1818class ProfileLangSkillEnum(models.Model):
1819 iso_639_2b = models.CharField(max_length=9, primary_key=True)
1820 language = models.CharField(max_length=765)
1821 language_en = models.CharField(max_length=765)
1822 iso_639_2t = models.CharField(max_length=9)
1823 iso_639_1 = models.CharField(max_length=6, blank=True)
1824 class Meta:
27b0b59f 1825 db_table = 'profile_langskill_enum'
f497e0a9 1826
27b0b59f 1827 def __str__(self):
f497e0a9
NI
1828 return self.iso_639_2b
1829
1830
27b0b59f 1831@python_2_unicode_compatible
f497e0a9
NI
1832class ProfileLangSkill(models.Model):
1833 profile = models.ForeignKey(Profile, db_column='pid')
1834 lang = models.ForeignKey(ProfileLangSkillEnum, db_column='lid')
1835 pkey = models.CompositeField(profile, lang, primary_key=True)
1836 level = models.IntegerField(null=True, blank=True)
1837 class Meta:
27b0b59f 1838 db_table = 'profile_langskills'
f497e0a9 1839
27b0b59f
NI
1840 def __str__(self):
1841 return "%s: %s" % (self.profile.hrpid, self.lang.iso_639_2b)
f497e0a9
NI
1842
1843
27b0b59f 1844@python_2_unicode_compatible
f497e0a9
NI
1845class ProfileSkillEnum(models.Model):
1846 id = models.CharField(max_length=9, primary_key=True)
1847 text_fr = models.CharField(max_length=330)
1848 text_en = models.CharField(max_length=330)
1849 flags = models.CharField(max_length=15)
1850 axfreetext = models.TextField()
1851 class Meta:
27b0b59f 1852 db_table = 'profile_skill_enum'
f497e0a9 1853
27b0b59f 1854 def __str__(self):
f497e0a9
NI
1855 return self.text_en
1856
1857
27b0b59f 1858@python_2_unicode_compatible
f497e0a9
NI
1859class ProfileSkill(models.Model):
1860 profile = models.ForeignKey(Profile, db_column='pid')
1861 skill = models.ForeignKey(ProfileSkillEnum, db_column='cid')
1862 pkey = models.CompositeField(profile, skill, primary_key=True)
1863 level = models.CharField(max_length=54)
1864 class Meta:
27b0b59f 1865 db_table = 'profile_skills'
f497e0a9 1866
27b0b59f
NI
1867 def __str__(self):
1868 return "%s: %s" % (self.profile.hrpid, self.skill.text_en)
f497e0a9
NI
1869
1870
1871# Profile::medals
1872# ---------------
1873
1874
1875class ProfileMedalEnum(models.Model):
1876 #id = models.IntegerField(primary_key=True)
1877 type = models.CharField(max_length=30)
1878 text = models.CharField(max_length=765, blank=True)
1879 img = models.CharField(max_length=765, blank=True)
1880 flags = models.CharField(max_length=63)
1881 class Meta:
27b0b59f 1882 db_table = 'profile_medal_enum'
f497e0a9
NI
1883
1884
1885class ProfileMedalGradeEnum(models.Model):
1886 medal = models.ForeignKey(ProfileMedalEnum, db_column='mid')
1887 gid = models.IntegerField()
1888 pkey = models.CompositeField(medal, gid, primary_key=True)
1889 text = models.CharField(max_length=765, blank=True)
1890 pos = models.IntegerField()
1891 class Meta:
27b0b59f 1892 db_table = 'profile_medal_grade_enum'
f497e0a9
NI
1893
1894
1895class ProfileMedal(models.Model):
1896 profile = models.ForeignKey(Profile, db_column='pid')
1897 medal = models.ForeignKey(ProfileMedalEnum)
1898 gid = models.IntegerField()
1899 grade = models.ForeignKey(ProfileMedalGradeEnum, to_field='pkey')
1900 pkey = models.CompositeField(profile, medal, gid, primary_key=True)
1901 level = models.CharField(max_length=18)
1902 class Meta:
27b0b59f 1903 db_table = 'profile_medals'
f497e0a9
NI
1904
1905
1906# Profile::mentor
1907# ---------------
1908
1909
1910class ProfileMentor(models.Model):
1911 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
1912 expertise = models.TextField()
1913 class Meta:
27b0b59f 1914 db_table = 'profile_mentor'
f497e0a9
NI
1915
1916
1917class ProfileMentorCountry(models.Model):
1918 profile = models.ForeignKey(Profile, db_column='pid')
1919 country = models.ForeignKey(GeolocCountry, db_column='country')
1920 pkey = models.CompositeField(profile, country, primary_key=True)
1921 class Meta:
27b0b59f 1922 db_table = 'profile_mentor_country'
f497e0a9
NI
1923
1924
1925class ProfileMentorTerm(models.Model):
1926 profile = models.ForeignKey(Profile, db_column='pid')
1927 job_term = models.ForeignKey(ProfileJobTermEnum, db_column='jtid')
1928 pkey = models.CompositeField(profile, job_term, primary_key=True)
1929 class Meta:
27b0b59f 1930 db_table = 'profile_mentor_term'
f497e0a9
NI
1931
1932
1933# Profile::partner
1934# ----------------
1935
1936
1937class ProfilePartnersharingEnum(models.Model):
1938 #id = models.IntegerField(primary_key=True)
1939 api_account = models.ForeignKey(Account, null=True, db_column='api_uid', blank=True)
1940 shortname = models.CharField(max_length=192)
1941 name = models.CharField(max_length=765)
1942 url = models.CharField(max_length=765)
1943 default_sharing_level = models.CharField(max_length=21, blank=True)
1944 has_directory = models.IntegerField()
1945 has_bulkmail = models.IntegerField()
1946 class Meta:
27b0b59f 1947 db_table = 'profile_partnersharing_enum'
f497e0a9
NI
1948
1949
1950class ProfilePartnersharingSetting(models.Model):
1951 profile = models.ForeignKey(Profile, db_column='pid')
1952 partner = models.ForeignKey(ProfilePartnersharingEnum)
1953 pkey = models.CompositeField(profile, partner, primary_key=True)
1954 exposed_uid = models.CharField(max_length=765)
1955 sharing_level = models.CharField(max_length=21, blank=True)
1956 allow_email = models.CharField(max_length=18, blank=True)
1957 last_connection = models.DateTimeField(null=True, blank=True)
1958 class Meta:
27b0b59f 1959 db_table = 'profile_partnersharing_settings'
f497e0a9
NI
1960
1961
1962class ProfilePhotoToken(models.Model):
1963 profile = models.ForeignKey(Profile, primary_key=True, db_column='pid')
1964 token = models.CharField(max_length=765)
1965 expires = models.DateTimeField()
1966 class Meta:
27b0b59f 1967 db_table = 'profile_photo_tokens'
f497e0a9
NI
1968
1969
1970# Profile::misc
1971# -------------
1972
1973
1974class ProfileMergeIssue(models.Model):
1975 profile = models.ForeignKey(Profile, primary_key=True, db_column='pid')
1976 issues = models.CharField(max_length=144, blank=True)
1977 entry_year_ax = models.IntegerField(null=True, blank=True)
1978 deathdate_ax = models.DateField(null=True, blank=True)
1979 name = models.CharField(max_length=765, blank=True)
1980 name_type = models.IntegerField(null=True, blank=True)
1981 class Meta:
27b0b59f 1982 db_table = 'profile_merge_issues'
f497e0a9
NI
1983
1984
1985class ProfileModification(models.Model):
1986 profile = models.ForeignKey(Profile, db_column='pid')
1987 account = models.ForeignKey(Account, db_column='uid')
1988 field = models.CharField(max_length=180)
1989 pkey = models.CompositeField(profile, field, primary_key=True)
1990 oldtext = models.TextField(db_column='oldText')
1991 newtext = models.TextField(db_column='newText')
1992 type = models.CharField(max_length=33)
1993 timestamp = models.DateTimeField()
1994 class Meta:
27b0b59f 1995 db_table = 'profile_modifications'
f497e0a9
NI
1996
1997
1998class ProfileVisibilityEnum(models.Model):
1999 access_level = models.CharField(max_length=21, blank=True, primary_key=True)
2000 best_display_level = models.CharField(max_length=21, blank=True)
2001 display_levels = models.CharField(max_length=72, blank=True)
2002 class Meta:
27b0b59f 2003 db_table = 'profile_visibility_enum'
f497e0a9
NI
2004
2005
2006
2007class ProfileDeltaten(models.Model):
2008 profile = models.OneToOneField(Profile, primary_key=True, db_column='pid')
2009 message = models.TextField()
2010 class Meta:
27b0b59f 2011 db_table = 'profile_deltaten'
f497e0a9
NI
2012
2013
2014# Reminders
2015# =========
2016
2017
2018class ReminderType(models.Model):
2019 #type_id = models.IntegerField(primary_key=True)
2020 name = models.CharField(max_length=255, unique=True)
2021 weight = models.IntegerField()
2022 remind_delay_yes = models.IntegerField()
2023 remind_delay_no = models.IntegerField()
2024 remind_delay_dismiss = models.IntegerField()
2025 class Meta:
27b0b59f 2026 db_table = 'reminder_type'
f497e0a9
NI
2027
2028
2029class Reminder(models.Model):
2030 account = models.ForeignKey(Account, db_column='uid')
2031 type = models.ForeignKey(ReminderType)
2032 pkey = models.CompositeField(account, type, primary_key=True)
2033 status = models.CharField(max_length=21)
2034 remind_last = models.DateTimeField()
2035 remind_next = models.DateTimeField(null=True, blank=True)
2036 class Meta:
27b0b59f 2037 db_table = 'reminder'
f497e0a9
NI
2038
2039
2040class ReminderTip(models.Model):
2041 #id = models.IntegerField(primary_key=True)
2042 title = models.CharField(max_length=192)
2043 text = models.TextField()
2044 priority = models.IntegerField()
2045 expiration = models.DateField()
2046 promo_min = models.IntegerField()
2047 promo_max = models.IntegerField()
2048 state = models.CharField(max_length=18)
2049 class Meta:
27b0b59f 2050 db_table = 'reminder_tips'
f497e0a9
NI
2051
2052
2053# Surveys
2054# =======
2055
2056
2057class Survey(models.Model):
2058 #id = models.IntegerField(primary_key=True)
2059 questions = models.TextField()
2060 title = models.CharField(max_length=765)
2061 description = models.TextField()
2062 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2063 end = models.DateField()
2064 mode = models.IntegerField()
2065 promos = models.CharField(max_length=765)
2066 class Meta:
27b0b59f 2067 db_table = 'surveys'
f497e0a9
NI
2068
2069
2070class SurveyVote(models.Model):
2071 #id = models.IntegerField(primary_key=True)
2072 survey = models.ForeignKey(Survey)
2073 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2074 class Meta:
27b0b59f 2075 db_table = 'survey_votes'
f497e0a9
NI
2076
2077
2078class SurveyAnswer(models.Model):
2079 #id = models.IntegerField(primary_key=True)
2080 vote = models.ForeignKey(SurveyVote)
2081 question_id = models.IntegerField()
2082 answer = models.TextField()
2083 class Meta:
27b0b59f 2084 db_table = 'survey_answers'
f497e0a9
NI
2085
2086
2087# GApps
2088# =====
2089
2090
2091class GappsAccount(models.Model):
2092 l_userid = models.ForeignKey(Account, null=True, db_column='l_userid', blank=True)
2093 l_sync_password = models.BooleanField(default=True)
2094 l_activate_mail_redirection = models.BooleanField(default=True)
2095 g_account_id = models.CharField(max_length=48, blank=True)
2096 g_account_name = models.CharField(max_length=255, primary_key=True)
2097 g_domain = models.CharField(max_length=120, blank=True)
2098 g_first_name = models.CharField(max_length=120)
2099 g_last_name = models.CharField(max_length=120)
2100 g_status = models.CharField(max_length=39, blank=True)
2101 g_admin = models.BooleanField()
2102 g_suspension = models.CharField(max_length=768, blank=True)
2103 r_disk_usage = models.BigIntegerField(null=True, blank=True)
2104 r_creation = models.DateField(null=True, blank=True)
2105 r_last_login = models.DateField(null=True, blank=True)
2106 r_last_webmail = models.DateField(null=True, blank=True)
2107 class Meta:
27b0b59f 2108 db_table = 'gapps_accounts'
f497e0a9
NI
2109
2110
2111class GappsNickname(models.Model):
2112 l_userid = models.ForeignKey(Account, null=True, db_column='l_userid', blank=True)
2113 g_account_name = models.CharField(max_length=768)
2114 g_nickname = models.CharField(max_length=255, primary_key=True)
2115 class Meta:
27b0b59f 2116 db_table = 'gapps_nicknames'
f497e0a9
NI
2117
2118
2119class GappsQueue(models.Model):
2120 q_id = models.AutoField(primary_key=True)
2121 q_owner = models.ForeignKey(Account, null=True, blank=True, related_name='owned_gapps_jobs')
2122 q_recipient = models.ForeignKey(Account, null=True, blank=True, related_name='received_gapps_jobs')
2123 p_entry_date = models.DateTimeField()
2124 p_notbefore_date = models.DateTimeField()
2125 p_start_date = models.DateTimeField(null=True, blank=True)
2126 p_end_date = models.DateTimeField(null=True, blank=True)
2127 p_status = models.CharField(max_length=24)
2128 p_priority = models.CharField(max_length=27)
2129 p_admin_request = models.BooleanField()
2130 j_type = models.CharField(max_length=30)
2131 j_parameters = models.TextField(blank=True)
2132 r_softfail_date = models.DateTimeField(null=True, blank=True)
2133 r_softfail_count = models.IntegerField()
2134 r_result = models.CharField(max_length=768, blank=True)
2135 class Meta:
27b0b59f 2136 db_table = 'gapps_queue'
f497e0a9
NI
2137
2138
2139class GappsReporting(models.Model):
2140 date = models.DateField(primary_key=True)
2141 num_accounts = models.IntegerField(null=True, blank=True)
2142 count_1_day_actives = models.IntegerField(null=True, blank=True)
2143 count_7_day_actives = models.IntegerField(null=True, blank=True)
2144 count_14_day_actives = models.IntegerField(null=True, blank=True)
2145 count_30_day_actives = models.IntegerField(null=True, blank=True)
2146 count_30_day_idle = models.IntegerField(null=True, blank=True)
2147 count_60_day_idle = models.IntegerField(null=True, blank=True)
2148 count_90_day_idle = models.IntegerField(null=True, blank=True)
2149 usage_in_bytes = models.BigIntegerField(null=True, blank=True)
2150 quota_in_mb = models.IntegerField(null=True, blank=True)
2151 class Meta:
27b0b59f 2152 db_table = 'gapps_reporting'
f497e0a9
NI
2153
2154
2155
2156# Watch
2157# =====
2158
2159
2160class Watch(models.Model):
2161 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2162 flags = models.CharField(max_length=39)
2163 actions = models.CharField(max_length=105)
2164 last = models.DateTimeField()
2165 class Meta:
27b0b59f 2166 db_table = 'watch'
f497e0a9
NI
2167
2168
2169class WatchGroup(models.Model):
2170 account = models.ForeignKey(Account, db_column='uid')
2171 group = models.ForeignKey(Group, db_column='groupid')
2172 pkey = models.CompositeField(account, group, primary_key=True)
2173 class Meta:
27b0b59f 2174 db_table = 'watch_group'
f497e0a9
NI
2175
2176
2177class WatchNonins(models.Model):
2178 account = models.ForeignKey(Account, db_column='uid', related_name='watching')
2179 watched = models.ForeignKey(Account, db_column='ni', related_name='watched_by')
2180 pkey = models.CompositeField(account, watched, primary_key=True)
2181 class Meta:
27b0b59f 2182 db_table = 'watch_nonins'
f497e0a9
NI
2183
2184
2185class WatchProfile(models.Model):
2186 profile = models.ForeignKey(Profile, db_column='pid')
2187 ts = models.DateTimeField()
2188 field = models.CharField(max_length=36)
2189 pkey = models.CompositeField(profile, field, primary_key=True)
2190 class Meta:
27b0b59f 2191 db_table = 'watch_profile'
f497e0a9
NI
2192
2193
2194class WatchPromo(models.Model):
2195 account = models.ForeignKey(Account, db_column='uid')
2196 promo = models.IntegerField()
2197 pkey = models.CompositeField(account, promo, primary_key=True)
2198 class Meta:
27b0b59f 2199 db_table = 'watch_promo'
f497e0a9
NI
2200
2201
2202# Postfix
2203# =======
2204
2205
2206class MxWatch(models.Model):
2207 host = models.CharField(max_length=192, primary_key=True)
2208 state = models.CharField(max_length=21, blank=True)
2209 text = models.TextField()
2210 class Meta:
27b0b59f 2211 db_table = 'mx_watch'
f497e0a9
NI
2212
2213
2214class PostfixBlacklist(models.Model):
2215 email = models.CharField(max_length=255, primary_key=True)
2216 reject_text = models.CharField(max_length=192)
2217 class Meta:
27b0b59f 2218 db_table = 'postfix_blacklist'
f497e0a9
NI
2219
2220
2221class PostfixMailseen(models.Model):
2222 crc = models.CharField(max_length=24, primary_key=True)
2223 nb = models.IntegerField()
2224 update_time = models.DateTimeField()
2225 create_time = models.DateTimeField()
2226 release = models.CharField(max_length=18)
2227 class Meta:
27b0b59f 2228 db_table = 'postfix_mailseen'
f497e0a9
NI
2229
2230
2231class PostfixWhitelist(models.Model):
2232 email = models.CharField(max_length=255, primary_key=True)
2233 class Meta:
27b0b59f 2234 db_table = 'postfix_whitelist'
f497e0a9
NI
2235
2236
2237# Register
2238# ========
2239
2240
2241class RegisterMarketing(models.Model):
2242 account = models.ForeignKey(Account, db_column='uid', related_name='received_marketings')
2243 sender = models.ForeignKey(Account, null=True, db_column='sender', blank=True, related_name='sent_marketings')
2244 email = models.CharField(max_length=765)
2245 pkey = models.CompositeField(account, email, primary_key=True)
2246
2247 date = models.DateField()
2248 last = models.DateField()
2249 nb = models.IntegerField()
2250 type = models.CharField(max_length=15, blank=True)
2251 hash = models.CharField(max_length=96)
2252 message = models.CharField(max_length=48)
2253 message_data = models.CharField(max_length=192, blank=True)
2254 personal_notes = models.TextField(blank=True)
2255 class Meta:
27b0b59f 2256 db_table = 'register_marketing'
f497e0a9
NI
2257
2258
2259class RegisterMstat(models.Model):
2260 account = models.OneToOneField(Account, primary_key=True, db_column='uid', related_name='received_marketings_stats')
2261 sender = models.ForeignKey(Account, null=True, db_column='sender', blank=True, related_name='sent_marketings_stats')
2262 success = models.DateField()
2263 class Meta:
27b0b59f 2264 db_table = 'register_mstats'
f497e0a9
NI
2265
2266
2267class RegisterPending(models.Model):
2268 account = models.OneToOneField(Account, primary_key=True, db_column='uid')
2269 forlife = models.CharField(max_length=255, unique=True)
2270 bestalias = models.CharField(max_length=255, unique=True)
2271 mailorg2 = models.CharField(max_length=765, blank=True)
2272 password = models.CharField(max_length=120)
2273 email = models.CharField(max_length=765)
2274 date = models.DateField()
2275 relance = models.DateField()
2276 naissance = models.DateField()
2277 hash = models.CharField(max_length=36)
2278 services = models.CharField(max_length=78)
2279 class Meta:
27b0b59f 2280 db_table = 'register_pending'
f497e0a9
NI
2281
2282
2283class RegisterPendingXnet(models.Model):
2284 account = models.ForeignKey(Account, primary_key=True, db_column='uid', related_name='pending_xnet_register')
2285 hruid = models.ForeignKey(Account, unique=True, db_column='hruid', related_name='pending_xnet_register_by_hruid')
2286 email = models.CharField(max_length=765)
2287 date = models.DateField()
2288 last_date = models.DateField(null=True, blank=True)
2289 hash = models.CharField(max_length=36)
2290 sender_name = models.CharField(max_length=765)
2291 group_name = models.CharField(max_length=765)
2292 class Meta:
27b0b59f 2293 db_table = 'register_pending_xnet'
f497e0a9
NI
2294
2295
2296class RegisterSubs(models.Model):
2297 account = models.ForeignKey(Account, db_column='uid')
2298 type = models.CharField(max_length=15)
2299 sub = models.CharField(max_length=96)
2300 domain = models.CharField(max_length=192)
2301 pkey = models.CompositeField(account, type, sub, domain, primary_key=True)
2302 class Meta:
27b0b59f 2303 db_table = 'register_subs'
f497e0a9
NI
2304
2305
2306# Search
2307# ======
2308
2309
2310class SearchAutocomplete(models.Model):
2311 name = models.CharField(max_length=60)
2312 query = models.CharField(max_length=300)
2313 pkey = models.CompositeField(name, query, primary_key=True)
2314 result = models.TextField()
2315 generated = models.DateTimeField()
2316 class Meta:
27b0b59f 2317 db_table = 'search_autocomplete'
f497e0a9
NI
2318
2319
2320class SearchName(models.Model):
2321 profile = models.ForeignKey(Profile, db_column='pid')
2322 token = models.CharField(max_length=765)
2323 pkey = models.CompositeField(profile, token, primary_key=True)
2324 score = models.IntegerField()
2325 soundex = models.CharField(max_length=12)
2326 flags = models.CharField(max_length=18)
2327 general_type = models.CharField(max_length=27)
2328 class Meta:
27b0b59f 2329 db_table = 'search_name'
f497e0a9
NI
2330
2331
2332# Requests
2333# ========
2334
2335
2336class Request(models.Model):
2337 account = models.ForeignKey(Account, db_column='uid')
2338 type = models.CharField(max_length=48)
2339 data = models.TextField()
2340 stamp = models.DateTimeField()
2341 profile = models.ForeignKey(Profile, null=True, db_column='pid', blank=True)
2342 pkey = models.CompositeField(account, stamp, type, primary_key=True)
2343 class Meta:
27b0b59f 2344 db_table = 'requests'
f497e0a9
NI
2345
2346
2347class RequestAnswer(models.Model):
2348 #id = models.IntegerField(primary_key=True)
2349 category = models.CharField(max_length=45)
2350 title = models.CharField(max_length=150)
2351 answer = models.TextField()
2352 class Meta:
27b0b59f 2353 db_table = 'requests_answers'
f497e0a9
NI
2354
2355
2356class RequestHidden(models.Model):
2357 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2358 hidden_requests = models.TextField()
2359 class Meta:
27b0b59f 2360 db_table = 'requests_hidden'
f497e0a9
NI
2361
2362
2363# Misc
2364# ====
2365
2366
2367class AXLetter(models.Model):
2368 #id = models.IntegerField(primary_key=True)
2369 short_name = models.CharField(max_length=48, unique=True, blank=True)
2370 subject = models.CharField(max_length=765)
2371 title = models.CharField(max_length=765)
2372 body = models.TextField()
2373 signature = models.TextField()
2374 promo_min = models.IntegerField()
2375 promo_max = models.IntegerField()
2376 subset = models.TextField(blank=True)
2377 subset_rm = models.IntegerField(null=True, blank=True)
2378 echeance = models.DateTimeField()
2379 date = models.DateField()
2380 bits = models.CharField(max_length=48)
2381 class Meta:
27b0b59f 2382 db_table = 'axletter'
f497e0a9
NI
2383
2384
2385class Carva(models.Model):
2386 account = models.ForeignKey(Account, primary_key=True, db_column='uid')
2387 url = models.CharField(max_length=765)
2388 class Meta:
27b0b59f 2389 db_table = 'carvas'
f497e0a9
NI
2390
2391
2392class Contact(models.Model):
2393 account = models.ForeignKey(Account, db_column='uid')
2394 contact = models.ForeignKey(Profile, db_column='contact')
2395 pkey = models.CompositeField(account, contact, primary_key=True)
2396 class Meta:
27b0b59f 2397 db_table = 'contacts'
f497e0a9
NI
2398
2399
2400class Downtime(models.Model):
2401 debut = models.DateTimeField()
2402 duree = models.TimeField() # This field type is a guess.
2403 resume = models.CharField(max_length=765)
2404 description = models.TextField()
2405 services = models.CharField(max_length=54)
2406 class Meta:
27b0b59f 2407 db_table = 'downtimes'
f497e0a9
NI
2408
2409
2410class EmailListModerate(models.Model):
2411 ml = models.CharField(max_length=192)
2412 domain = models.CharField(max_length=192)
2413 mid = models.IntegerField()
2414 pkey = models.CompositeField(ml, domain, mid, primary_key=True)
2415 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2416 action = models.CharField(max_length=18)
2417 ts = models.DateTimeField()
2418 message = models.TextField(blank=True)
2419 handler = models.IntegerField(null=True, blank=True)
2420 class Meta:
27b0b59f 2421 db_table = 'email_list_moderate'
f497e0a9
NI
2422
2423
2424class EmailSendSave(models.Model):
2425 account = models.OneToOneField(Account, primary_key=True, db_column='uid')
2426 data = models.TextField()
2427 class Meta:
27b0b59f 2428 db_table = 'email_send_save'
f497e0a9
NI
2429
2430
2431class EmailWatch(models.Model):
2432 email = models.CharField(max_length=180, primary_key=True)
2433 state = models.CharField(max_length=27)
2434 detection = models.DateField(null=True, blank=True)
2435 last = models.DateTimeField()
2436 account = models.ForeignKey(Account, null=True, db_column='uid', blank=True)
2437 description = models.TextField()
2438 class Meta:
27b0b59f 2439 db_table = 'email_watch'
f497e0a9
NI
2440
2441
2442class GeolocLanguage(models.Model):
2443 iso_3166_1_a2 = models.ForeignKey(GeolocCountry, db_column='iso_3166_1_a2')
2444 language = models.CharField(max_length=15)
2445 pkey = models.CompositeField(iso_3166_1_a2, language, primary_key=True)
2446 country = models.CharField(max_length=765, blank=True)
2447 countryplain = models.CharField(max_length=765, db_column='countryPlain', blank=True) # Field name made lowercase.
2448 class Meta:
27b0b59f 2449 db_table = 'geoloc_languages'
f497e0a9
NI
2450
2451
2452class HomonymList(models.Model):
2453 hrmid = models.CharField(max_length=765)
2454 account = models.ForeignKey(Account, db_column='uid')
2455 pkey = models.CompositeField(hrmid, account, primary_key=True)
2456 class Meta:
27b0b59f 2457 db_table = 'homonyms_list'
f497e0a9
NI
2458
2459
2460class UrlShortener(models.Model):
2461 alias = models.CharField(max_length=255, primary_key=True)
2462 url = models.TextField()
2463 class Meta:
27b0b59f 2464 db_table = 'url_shortener'