diff options
| author | Étienne Loks <etienne.loks@proxience.com> | 2015-05-03 23:21:46 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@proxience.com> | 2015-05-03 23:21:46 +0200 | 
| commit | 0500c0a5098c2b3347ffd36faaa692e97be3b5a4 (patch) | |
| tree | 9d23175660bb6b6d1adcbcec722bf4ea88f0b818 /ishtar_common/models.py | |
| parent | 5429ff2d3639bc96dc6bbd9d45a60a490a555775 (diff) | |
| download | Ishtar-0500c0a5098c2b3347ffd36faaa692e97be3b5a4.tar.bz2 Ishtar-0500c0a5098c2b3347ffd36faaa692e97be3b5a4.zip | |
Interface: create new import, management interface
Diffstat (limited to 'ishtar_common/models.py')
| -rw-r--r-- | ishtar_common/models.py | 96 | 
1 files changed, 69 insertions, 27 deletions
| diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 1f059f2f5..b43d3a50c 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -973,11 +973,15 @@ def get_model_fields(model):      """      fields = {}      options = model._meta -    for field in sorted(options.concrete_fields + options.many_to_many + -                        options.virtual_fields): +    for field in sorted(options.fields):          fields[field.name] = field      return fields +def import_class(full_path_classname): +    mods = full_path_classname.split('.') +    module = import_module('.'.join(mods[:-1])) +    return getattr(module, mods[-1]) +  class ImporterType(models.Model):      """      Description of a table to be mapped with ishtar database @@ -998,22 +1002,19 @@ class ImporterType(models.Model):      def __unicode__(self):          return self.name -    @property -    def importer_class(self): -        name = ''.join(x for x in slugify(self.name).replace('-', ' ').title() -                       if not x.isspace()) -        OBJECT_CLS = import_module(self.associated_models) -        DEFAULTS = dict((default.keys, default.values) -                                        for default in self.defaults.all()) +    def get_importer_class(self): +        OBJECT_CLS = import_class(self.associated_models) +        DEFAULTS = dict([(default.keys, default.values) +                                        for default in self.defaults.all()])          LINE_FORMAT = []          idx = 0          for column in self.columns.order_by('col_number').all():              idx += 1 -            while column.order > idx: +            while column.col_number > idx:                  LINE_FORMAT.append(None)                  idx += 1 -            targets = None -            formater_types = None +            targets = [] +            formater_types = []              nb = column.targets.count()              if not nb:                  LINE_FORMAT.append(None) @@ -1035,6 +1036,8 @@ class ImporterType(models.Model):              LINE_FORMAT.append(formater)          args = {'OBJECT_CLS':OBJECT_CLS, 'DESC':self.description,                  'DEFAULTS':DEFAULTS, 'LINE_FORMAT':LINE_FORMAT} +        name = str(''.join(x for x in slugify(self.name).replace('-', ' ').title() +                       if not x.isspace()))          newclass = type(name, (Importer,), args)          return newclass @@ -1050,12 +1053,12 @@ class ImporterDefault(models.Model):      @property      def keys(self): -        return default.target.split('__') +        return tuple(self.target.split('__'))      @property      def associated_model(self):          field = None -        OBJECT_CLS = import_module(self.importer_type.associated_models) +        OBJECT_CLS = import_class(self.importer_type.associated_models)          for idx, item in enumerate(self.keys):              if not idx:                  field = get_model_fields(OBJECT_CLS)[item] @@ -1084,9 +1087,17 @@ class ImporterDefaultValues(models.Model):          verbose_name_plural = _(u"Importer - Default values")      def get_value(self): -        model = self.default_target.associated_model -        if not model: +        parent_model = self.default_target.associated_model +        if not parent_model:              return self.value +        fields = get_model_fields(parent_model) +        target = self.target.strip() +        if target not in fields: +            return +        field = fields[target] +        if not hasattr(field, 'rel') or not hasattr(field.rel, 'to'): +            return +        model = field.rel.to          # if value is an id          try:              return model.objects.get(pk=int(self.value)) @@ -1154,7 +1165,7 @@ class TargetKey(models.Model):      Also temporary used for GeneralType to point missing link before adding      them in ItemKey table      """ -    target = models.ForeignKey(ImporterColumn, related_name='keys') +    target = models.ForeignKey(ImportTarget, related_name='keys')      key = models.TextField(_(u"Key"), blank=True, null=True)      value = models.TextField(_(u"Value"))      is_set = models.BooleanField(_(u"Is set"), default=False) @@ -1174,7 +1185,7 @@ TARGET_MODELS = [      ('archaeological_operations.models.Period', _(u"Period")),      ] -TARGET_MODELS_KEYS = (tm[0] for tm in TARGET_MODELS) +TARGET_MODELS_KEYS = [tm[0] for tm in TARGET_MODELS]  IMPORTER_TYPES = (      ('IntegerFormater', _(u"Integer")), @@ -1226,7 +1237,7 @@ class FormaterType(models.Model):      def get_formater_type(self, target):          if self.formater_type not in IMPORTER_TYPES_DCT.keys():              return -        kwargs = {'target':target} +        kwargs = {'db_target':target}          if self.many_split:              kwargs['many_split'] = self.many_split          if self.formater_type == 'TypeFormater': @@ -1236,18 +1247,18 @@ class FormaterType(models.Model):              if self.options in dir():                  model = dir()[self.options]              else: -                model = import_module(self.options) +                model = import_class(self.options)              return TypeFormater(model, **kwargs)          elif self.formater_type == 'IntegerFormater':              return IntegerFormater(**kwargs)          elif self.formater_type == 'FloatFormater':              return FloatFormater(**kwargs) -        elif self.format_type == 'UnicodeFormater': +        elif self.formater_type == 'UnicodeFormater':              try:                  return UnicodeFormater(int(self.options.strip()), **kwargs)              except ValueError:                  return -        elif self.format_type == 'DateFormater': +        elif self.formater_type == 'DateFormater':              return DateFormater(self.options, **kwargs)  IMPORT_STATE = (("C", _(u"Created")), @@ -1257,6 +1268,8 @@ IMPORT_STATE = (("C", _(u"Created")),                  ("IP", _(u"Import in progress")),                  ("F", _(u"Finished"))) +IMPORT_STATE_DCT = dict(IMPORT_STATE) +  class Import(models.Model):      user = models.ForeignKey('IshtarUser')      importer_type = models.ForeignKey(ImporterType) @@ -1285,15 +1298,40 @@ class Import(models.Model):          return u"%s - %s" % (unicode(self.importer_type),                               unicode(self.user)) +    def get_actions(self): +        """ +        Get available action relevant with the current status +        """ +        actions = [] +        if self.state == 'C': +            actions.append(('A', _(u"Analyse"))) +        if self.state == 'A': +            if ImporterType.objects.filter(pk=self.importer_type.pk, +                               columns__targets__keys__is_set=False).count(): +                actions.append(('L', _(u"Link unmatched items"))) +            actions.append(('A', _(u"Re-analyse"))) +            actions.append(('I', _(u"Launch import"))) +        actions.append(('D', _(u"Delete"))) +        return actions +      @property -    def importer_instance(self): -        return self.importer_type.importer_class(skip_lines=self.skip_lines, -                                                 import_instance=self) +    def imported_filename(self): +        return self.imported_file.name.split(os.sep)[-1] + +    @property +    def status(self): +        if self.state not in IMPORT_STATE_DCT: +            return "" +        return IMPORT_STATE_DCT[self.state] + +    def get_importer_instance(self): +        return self.importer_type.get_importer_class()( +                        skip_lines=self.skip_lines, import_instance=self)      @property      def data_table(self):          encodings = [settings.ENCODING, settings.ALT_ENCODING, 'utf-8'] -        with open(self.imported_file.filename) as csv_file: +        with open(self.imported_file.path) as csv_file:              for encoding in encodings:                  try:                      return [line for line in unicodecsv.reader(csv_file, @@ -1305,7 +1343,11 @@ class Import(models.Model):          return []      def initialize(self): -        self.importer_instance.initialize(self.data_table, output='db') +        self.state = 'AP' +        self.save() +        self.get_importer_instance().initialize(self.data_table, output='db') +        self.state = 'A' +        self.save()  class Organization(Address, Merge, OwnPerms, ValueGetter):      TABLE_COLS = ('name', 'organization_type',) | 
