class Article(BlogPost, SubTitled):
- related_articles = models.ManyToManyField("self",
- verbose_name=_("Related articles"), blank=True)
+ related_articles = models.ManyToManyField("self", verbose_name=_("Related articles"), blank=True)
department = models.ForeignKey(Department, verbose_name=_('department'), related_name='articles', limit_choices_to=dict(id__in=Department.objects.all()), blank=True, null=True, on_delete=models.SET_NULL)
topics = models.ManyToManyField("Topic", verbose_name=_('topics'), related_name="articles", blank=True)
--- /dev/null
+import os
+import sys
+import csv
+import logging
+import datetime
+from optparse import make_option
+import xlrd
+from itertools import takewhile
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.auth.models import User
+
+from organization.core.models import *
+from organization.network.models import *
+from organization.projects.models import *
+
+
+class Logger:
+
+ def __init__(self, file):
+ self.logger = logging.getLogger('myapp')
+ self.hdlr = logging.FileHandler(file)
+ self.formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+ self.hdlr.setFormatter(self.formatter)
+ self.logger.addHandler(self.hdlr)
+ self.logger.setLevel(logging.INFO)
+
+ def info(self, prefix, message):
+ self.logger.info(' ' + prefix + ' : ' + message.decode('utf8'))
+
+ def error(self, prefix, message):
+ self.logger.error(prefix + ' : ' + message.decode('utf8'))
+
+
+def get_instance(model, field, value):
+ models = model.objects.filter(field=value)
+ if models:
+ return models[0]
+ else:
+ model = model()
+ model.field = value
+ return model
+
+
+class IrcamXLS:
+
+ sheet_id = 2
+ first_row = 21
+
+ def __init__(self, file):
+ self.book = xlrd.open_workbook(file)
+ self.sheet = self.book.sheet_by_index(self.sheet_id)
+ self.size = self.column_len(0)
+
+ def column_len(self, index):
+ col_values = self.sheet.col_values(index)
+ col_len = len(col_values)
+ for _ in takewhile(lambda x: not x, reversed(col_values)):
+ col_len -= 1
+ return col_len
+
+class IrcamPerson(object):
+
+ organization = Organization.objects.get(name='Ircam')
+
+ def __init__(self, row, datemode):
+ self.row = row
+ self.datemode = datemode
+ last_name = self.row[0].value
+ first_name = self.row[1].value
+ title = ' '.join((first_name, last_name))
+
+ self.person, c = Person.objects.get_or_create(title=title, first_name=first_name, last_name=last_name)
+ self.activity = PersonActivity(person=self.person)
+
+ def get_identity(self, ):
+ gender = self.row[2].value
+ if gender == 'H':
+ self.person.gender = 'male'
+ elif gender == 'F':
+ self.person.gender = 'female'
+
+ birthday = self.row[3].value
+ if birthday:
+ self.person.birthday = datetime.datetime(*xlrd.xldate_as_tuple(birthday, self.datemode))
+
+ self.person.save()
+
+ def get_or_create_name(self, model, column_id):
+ return model.objects.get_or_create(name=self.row[column_id].value)[0] if self.row[column_id].value else None
+
+ def get_activity(self):
+ self.activity.status = self.get_or_create_name(ActivityStatus, 10)
+ self.activity.is_permanent = True if self.row[11].value else False
+ self.activity.framework = self.get_or_create_name(ActivityFramework, 12)
+ self.activity.grade = self.get_or_create_name(ActivityGrade, 13)
+
+ self.activity.employer = self.get_or_create_name(Organization, 14)
+ self.activity.attachment_organization = self.get_or_create_name(Organization, 15)
+ self.activity.second_employer = self.get_or_create_name(Organization, 16)
+ self.activity.umr = self.get_or_create_name(UMR, 17)
+
+ self.activity.team, c = Team.objects.get_or_create(name=self.row[18].value, organization=self.organization) if self.row[18].value else (None, False)
+ self.activity.second_team, c = Team.objects.get_or_create(name=self.row[19].value, organization=self.organization) if self.row[19].value else (None, False)
+ self.activity.project, c = Project.objects.get_or_create(title=self.row[19].value) if self.row[19].value else (None, False)
+
+ quota = self.row[21].value
+ try:
+ self.activity.rd_quota_float = float(quota)
+ except:
+ self.activity.rd_quota_text = str(quota)
+
+ self.activity.phd_doctoral_school = self.get_or_create_name(Organization, 23)
+ self.activity.phd_director, c = Person.objects.get_or_create(title=self.row[24].value.capitalize()) if self.row[24].value else (None, False)
+ self.activity.phd_officer_1, c = Person.objects.get_or_create(title=self.row[25].value.capitalize()) if self.row[25].value else (None, False)
+ self.activity.phd_officer_2, c = Person.objects.get_or_create(title=self.row[26].value.capitalize()) if self.row[26].value else (None, False)
+ # self.activity.phd_defense_date = datetime.datetime(*xlrd.xldate_as_tuple(self.row[27].value, self.datemode)) if self.row[27].value else None
+ # self.activity.phd_title = self.row[28].value
+
+ self.activity.save()
+
+
+class Command(BaseCommand):
+ help = """Import Person data from IRCAM's legacy XLS management file"""
+
+ option_list = BaseCommand.option_list + (
+ make_option('-d', '--dry-run',
+ action='store_true',
+ dest='dry-run',
+ help='Do NOT write anything'),
+ make_option('-f', '--force',
+ action='store_true',
+ dest='force',
+ help='Force overwrite data'),
+ make_option('-s', '--source',
+ dest='source_file',
+ help='define the XLS source file'),
+ make_option('-l', '--log',
+ dest='log',
+ help='define log file'),
+ )
+
+ def handle(self, *args, **kwargs):
+ # self.logger = Logger(kwargs.get('log'))
+ self.pattern = kwargs.get('pattern')
+ self.source_file = os.path.abspath(kwargs.get('source_file'))
+ self.dry_run = kwargs.get('dry-run')
+ self.force = kwargs.get('force')
+
+ xls = IrcamXLS(self.source_file)
+ for i in range(xls.first_row, xls.size):
+ p = IrcamPerson(xls.sheet.row(i), xls.book.datemode)
+ p.get_identity()
+ p.get_activity()
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-05 16:53
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-network', '0004_organizationaudio_organizationblock_organizationimage_organizationlink_organizationvideo'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='UMR',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=512, verbose_name='name')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ],
+ options={
+ 'verbose_name': 'UMR',
+ },
+ ),
+ migrations.RemoveField(
+ model_name='person',
+ name='permanent',
+ ),
+ migrations.RemoveField(
+ model_name='personactivity',
+ name='function',
+ ),
+ migrations.RemoveField(
+ model_name='personactivity',
+ name='rd_quota',
+ ),
+ migrations.AddField(
+ model_name='personactivity',
+ name='is_permanent',
+ field=models.BooleanField(default=False, verbose_name='permanent'),
+ ),
+ migrations.AddField(
+ model_name='personactivity',
+ name='rd_quota_float',
+ field=models.IntegerField(blank=True, null=True, verbose_name='R&D quota (float)'),
+ ),
+ migrations.AddField(
+ model_name='personactivity',
+ name='rd_quota_text',
+ field=models.CharField(blank=True, max_length=128, null=True, verbose_name='R&D quota (text)'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='user',
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user'),
+ ),
+ migrations.AddField(
+ model_name='personactivity',
+ name='umr',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-network.UMR', verbose_name='training type'),
+ ),
+ ]
class Person(Displayable, AdminThumbMixin):
"""(Person description)"""
- user = models.ForeignKey(User, verbose_name=_('user'), blank=True, null=True, on_delete=models.SET_NULL)
+ user = models.OneToOneField(User, verbose_name=_('user'), blank=True, null=True, on_delete=models.SET_NULL)
person_title = models.CharField(_('title'), max_length=16, choices=TITLE_CHOICES, blank=True)
gender = models.CharField(_('gender'), max_length=16, choices=GENDER_CHOICES, blank=True)
first_name = models.CharField(_('first name'), max_length=255, blank=True, null=True)
last_name = models.CharField(_('last name'), max_length=255, blank=True, null=True)
birthday = models.DateField(_('birthday'), blank=True, null=True)
bio = RichTextField(_('biography'), blank=True)
- permanent = models.BooleanField(_('permanent'), default=False)
class Meta:
verbose_name = _('person')
verbose_name = _('training speciality')
+class UMR(Named):
+
+ class Meta:
+ verbose_name = _('UMR')
+
+
class PersonActivity(Description, Period, RichText):
"""(Activity description)"""
person = models.ForeignKey('Person', verbose_name=_('person'))
- team = models.ForeignKey('Team', verbose_name=_('team'), related_name='team_activity', blank=True, null=True, on_delete=models.SET_NULL)
- second_team = models.ForeignKey('Team', verbose_name=_('second team'), related_name='second_team_activity', blank=True, null=True, on_delete=models.SET_NULL)
- function = models.CharField(_('fonction'), blank=True, max_length=1024)
status = models.ForeignKey(ActivityStatus, verbose_name=_('status'), blank=True, null=True, on_delete=models.SET_NULL)
- grade = models.ForeignKey(ActivityGrade, verbose_name=_('grade'), blank=True, null=True, on_delete=models.SET_NULL)
+ is_permanent = models.BooleanField(_('permanent'), default=False)
framework = models.ForeignKey(ActivityFramework, verbose_name=_('framework'), blank=True, null=True, on_delete=models.SET_NULL)
- hdr = models.BooleanField(_('HDR'), default=False)
+ grade = models.ForeignKey(ActivityGrade, verbose_name=_('grade'), blank=True, null=True, on_delete=models.SET_NULL)
employer = models.ForeignKey(Organization, verbose_name=_('employer'), related_name='employer_activity', blank=True, null=True, on_delete=models.SET_NULL)
- second_employer = models.ForeignKey(Organization, verbose_name=_('second employer'), related_name='second_employer_activity', blank=True, null=True, on_delete=models.SET_NULL)
attachment_organization = models.ForeignKey(Organization, verbose_name=_('attachment organization'), related_name='attachment_activity', blank=True, null=True, on_delete=models.SET_NULL)
+ second_employer = models.ForeignKey(Organization, verbose_name=_('second employer'), related_name='second_employer_activity', blank=True, null=True, on_delete=models.SET_NULL)
+ umr = models.ForeignKey(UMR, verbose_name=_('training type'), blank=True, null=True, on_delete=models.SET_NULL)
+ team = models.ForeignKey('Team', verbose_name=_('team'), related_name='team_activity', blank=True, null=True, on_delete=models.SET_NULL)
+ second_team = models.ForeignKey('Team', verbose_name=_('second team'), related_name='second_team_activity', blank=True, null=True, on_delete=models.SET_NULL)
project = models.ForeignKey('organization-projects.Project', verbose_name=_('project'), blank=True, null=True, on_delete=models.SET_NULL)
- rd_quota = models.IntegerField(_('R&D quota'), blank=True, null=True)
+ rd_quota_float = models.IntegerField(_('R&D quota (float)'), blank=True, null=True)
+ rd_quota_text = models.CharField(_('R&D quota (text)'), blank=True, null=True, max_length=128)
rd_program = models.TextField(_('R&D program'), blank=True)
budget_code = models.ForeignKey(BudgetCode, blank=True, null=True, on_delete=models.SET_NULL)
phd_defense_date = models.DateField(_('PhD defense date'), blank=True, null=True)
phd_title = models.TextField(_('PhD title'), blank=True)
phd_postdoctoralsituation = models.CharField(_('post-doctoral situation'), blank=True, max_length=256)
+ hdr = models.BooleanField(_('HDR'), default=False)
training_type = models.ForeignKey(TrainingType, verbose_name=_('training type'), blank=True, null=True, on_delete=models.SET_NULL)
training_level = models.ForeignKey(TrainingLevel, verbose_name=_('training level'), blank=True, null=True, on_delete=models.SET_NULL)
training_speciality = models.ForeignKey(TrainingSpectiality, verbose_name=_('training speciality'), blank=True, null=True, on_delete=models.SET_NULL)
training_title = models.TextField(_('Training title'), blank=True)
- comments = models.TextField(_('comments'), blank=True)
-
record_piece = models.ForeignKey(RecordPiece, blank=True, null=True, on_delete=models.SET_NULL)
date_added = models.DateTimeField(_('add date'), auto_now_add=True)
date_modified = models.DateTimeField(_('modification date'), auto_now=True)
date_modified_manual = models.DateTimeField(_('manual modification date'), blank=True, null=True)
+ comments = models.TextField(_('comments'), blank=True)
+
class Meta:
verbose_name = _('activity')
verbose_name_plural = _('activities')
fieldsets = deepcopy(ProjectAdmin.fieldsets)
inlines = [ ProjectBlockInline, ProjectImageInline, ProjectAudioInline, ProjectVideoInline, ProjectLinkInline]
filter_horizontal = ['persons', 'teams', 'organizations']
+ list_filter = ['type', 'program', 'program_type', ]
admin.site.register(Project, ProjectAdminDisplayable)
+admin.site.register(ProjectProgram)
+admin.site.register(ProjectProgramType)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-05 16:53
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-projects', '0003_auto_20160901_1810'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ProjectProgram',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=512, verbose_name='name')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ],
+ options={
+ 'verbose_name': 'project programme',
+ },
+ ),
+ migrations.CreateModel(
+ name='ProjectProgramType',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=512, verbose_name='name')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ],
+ options={
+ 'verbose_name': 'project programme type',
+ },
+ ),
+ migrations.AddField(
+ model_name='project',
+ name='type',
+ field=models.CharField(choices=[('research topic', 'research topic'), ('collaborative project', 'collaborative project')], default=1, max_length=128, verbose_name='type'),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='project',
+ name='teams',
+ field=models.ManyToManyField(blank=True, related_name='partner_projects', to='organization-network.Team', verbose_name='teams'),
+ ),
+ migrations.AddField(
+ model_name='project',
+ name='program',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='projects', to='organization-projects.ProjectProgram', verbose_name='project program'),
+ ),
+ migrations.AddField(
+ model_name='project',
+ name='program_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='projects', to='organization-projects.ProjectProgramType', verbose_name='project program type'),
+ ),
+ ]
from organization.pages.models import *
+PROJECT_TYPE_CHOICES = [
+ ('internal project', _('internal project')),
+ ('external project', _('external project')),
+]
+
class Project(Displayable, Period, RichText):
"""(Project description)"""
+ type = models.CharField(_('type'), max_length=128, choices=PROJECT_TYPE_CHOICES)
+ program = models.ForeignKey('ProjectProgram', verbose_name=_('project program'), related_name='projects', blank=True, null=True, on_delete=models.SET_NULL)
+ program_type = models.ForeignKey('ProjectProgramType', verbose_name=_('project program type'), related_name='projects', blank=True, null=True, on_delete=models.SET_NULL)
lead_team = models.ForeignKey('organization-network.Team', verbose_name=_('lead team'), related_name='leader_projects', blank=True, null=True)
persons = models.ManyToManyField('organization-network.Person', verbose_name=_('persons'), blank=True)
- teams = models.ManyToManyField('organization-network.Team', verbose_name=_('teams'), related_name='patner_projects', blank=True)
+ teams = models.ManyToManyField('organization-network.Team', verbose_name=_('teams'), related_name='partner_projects', blank=True)
organizations = models.ManyToManyField('organization-network.Organization', verbose_name=_('organizations'), blank=True)
website = models.URLField(_('website'), max_length=512, blank=True)
return reverse("organization-project-detail", kwargs={"slug": self.slug})
+class ProjectProgram(Named):
+
+ class Meta:
+ verbose_name = _('project programme')
+
+
+class ProjectProgramType(Named):
+
+ class Meta:
+ verbose_name = _('project programme type')
+
+
class ProjectAudio(Audio):
project = models.ForeignKey(Project, verbose_name=_('project'), related_name='audios', blank=True, null=True, on_delete=models.SET_NULL)