Changeset 3133


Ignore:
Timestamp:
9 Feb 2008, 09:15:05 (17 years ago)
Author:
joachim
Message:

implement new functionality im importData:

  • for verdicts and course_results now records, which return an "id" and

"error" in their mass_edit-function are collected into files named:

verdict_pending.csv for verdicts
or course_result_pending.csv for course_results

These files are checked first, when importing new data, and importable
records are imported and removed from this file.

There are also the options:

Pending Verdicts only
Pending CourseResults? only

to import the pending records only.

The input file is irrelevant then.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • WAeUP_SRP/base/WAeUPTool.py

    r3114 r3133  
    15961596    security.declareProtected(ModifyPortalContent,'mass_edit_course_result') ###(
    15971597    def mass_edit_course_result(self,mapping):
    1598         id_key = ''
    1599         for id_key in ('student_id','matric_no'):
    1600             id_field = mapping.get(id_key,None)
    1601             if id_field is not None:
    1602                 student_id = id_field
     1598        while True:
     1599            result_id = mapping.get('id',None)
     1600            if result_id is not None:
     1601                mapping['key'] = key = result_id
    16031602                break
    1604         query = Eq(id_key,id_field)
    1605         res = self.students_catalog.evalAdvancedQuery(query)
    1606         if not res:
    1607             return '', "No student with %(id_key)s %(id_field)s" % vars()
    1608         if id_field != "student_id":
    1609             mapping['student_id'] = res[0].id
    1610         if not res:
    1611             return '', "No student with %(id_key)s %(id_field)s" % vars()
    1612         student_rec = res[0]
    1613         student_id = student_rec.id
    1614         level_id = mapping['level_id']
    1615         code = mapping['code']
    1616         mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
     1603            for id_key in ('student_id','matric_no'):
     1604                id_field = mapping.get(id_key,None)
     1605                if id_field is not None:
     1606                    student_id = id_field
     1607                    break
     1608            query = Eq(id_key,id_field)
     1609            res = self.students_catalog.evalAdvancedQuery(query)
     1610            if not res:
     1611                return '', "No student with %(id_key)s %(id_field)s" % vars()
     1612            if id_field != "student_id":
     1613                mapping['student_id'] = res[0].id
     1614            if not res:
     1615                return '', "No student with %(id_key)s %(id_field)s" % vars()
     1616            student_rec = res[0]
     1617            student_id = student_rec.id
     1618            level_id = mapping['level_id']
     1619            code = mapping['code']
     1620            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
     1621            break
    16171622        try:
    16181623            self.course_results.modifyRecord(**mapping)
    16191624        except KeyError:
    1620             return '', "No course result to edit: %s" % key
     1625            return key, "No course result to edit: %s" % key
    16211626        return key,''
    16221627    ###)
     
    19691974            return '',"no id or matric_no specified"
    19701975        student_id = student_record.id
    1971         student_review_state =  student_record.review_state
    1972         if student_review_state not in ('courses_validated','returning'):
    1973             return '',"student %s in wrong review_state %s" % (student_id, student_review_state)
    19741976        student_obj = getattr(students_folder,student_id)
    19751977        f2t = self.field2types_student
     
    19801982        current_session = d['session'] = mapping.get('current_session','')
    19811983        if current_session and student_record.session != current_session:
    1982             return '','student %s: imported session %s does not match current_session %s' % (student_id,
     1984            return student_id,'student %s: imported session %s does not match current_session %s' % (student_id,
    19831985                                                                                        current_session,
    19841986                                                                                        student_record.session)
    19851987        current_level = mapping.get('current_level','')
     1988        if not current_level.isdigit():
     1989            return '','student %s: imported level is empty' % (student_id,)
    19861990        if current_level and student_record.level != current_level:
    1987             return '','student %s: imported level %s does not match current_level %s' % (student_id,
     1991            return student_id,'student %s: imported level %s does not match current_level %s' % (student_id,
    19881992                                                                                    current_level,
    19891993                                                                                    student_record.level)
     1994        student_review_state =  student_record.review_state
     1995        if student_review_state not in ('courses_validated','returning'):
     1996            return student_id,"student %s in wrong review_state %s" % (student_id, student_review_state)
    19901997        study_course_obj = getattr(student_obj,'study_course',None)
    19911998        if study_course_obj is None:
     
    20202027    security.declareProtected(ModifyPortalContent,"importData")###(
    20212028    def importData(self,filename,name,edit=False,bypass_queue_catalog=False):
     2029        """load data from CSV values"""
     2030        import transaction
     2031        import random
     2032        member = self.portal_membership.getAuthenticatedMember()
     2033        logger = logging.getLogger('WAeUPTool.importData')
     2034        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
     2035        students_folder = self.portal_url.getPortalObject().campus.students
     2036        start = True
     2037        tr_count = 0
     2038        total_imported = 0
     2039        total_not_imported = 0
     2040        total = 0
     2041        pending_only = False
     2042        pend_str = '_pending'
     2043        if name.endswith(pend_str):
     2044            pending_only = True
     2045            name = name[:-len(pend_str)]
     2046        iname = "import_%s" % name
     2047        if name in ('application','course_result',):
     2048            commit_after = 2000
     2049        else:
     2050            commit_after = 100
     2051        stool = getToolByName(self, 'portal_schemas')
     2052        ltool = getToolByName(self, 'portal_layouts')
     2053        schema = stool._getOb(iname)
     2054        if schema is None:
     2055            em = 'No such schema %s' % iname
     2056            logger.error('No such schema %s' % iname)
     2057            return em
     2058        layout = ltool._getOb(iname)
     2059        if layout is None:
     2060            em = 'No such layout %s' % iname
     2061            logger.error(em)
     2062            return em
     2063        validators = {}
     2064        for widget in layout.keys():
     2065            validators[widget] = layout[widget].validate
     2066        mode = "create"
     2067        if edit:
     2068            if filename.endswith('_toDelete'):
     2069                mode = "delete"
     2070            else:
     2071                mode = "edit"
     2072        importer_name = "mass_%(mode)s_%(name)s" % vars()
     2073        importer = getattr(self, '%s' % importer_name,None)
     2074        if importer is None:
     2075            em = 'No importer function %s' % importer_name
     2076            logger.error(em)
     2077            return em
     2078        pending_fn = "%s/import/%s_pending.csv" % (i_home,name)
     2079        if pending_only:
     2080            import_source_fn = pending_fn
     2081            imported_fn = "%s/import/%s_pending_imported%s.csv" % (i_home,name,current)
     2082            not_imported_fn = "%s/import/%s_pending_not_imported%s.csv" % (i_home,name,current)
     2083            attrs = csv.reader(open(pending_fn,"rb")).next()
     2084        else:
     2085            import_source_fn = "%s/import/%s.csv" % (i_home,filename)
     2086            imported_fn = "%s/import/%s_imported%s.csv" % (i_home,filename,current)
     2087            not_imported_fn = "%s/import/%s_not_imported%s.csv" % (i_home,filename,current)
     2088            attrs = csv.reader(open(import_source_fn,"rb")).next()
     2089        import_keys = [k.strip() for k in attrs if not (k.strip().startswith('ignore')
     2090                                                        or k.strip() == 'Error')]
     2091        diff2schema = set(import_keys).difference(set(schema.keys()))
     2092        diff2layout = set(import_keys).difference(set(layout.keys()))
     2093        if diff2schema and diff2schema != set(['id',]):
     2094            #import pdb;pdb.set_trace()
     2095            msg = 'not ignorable key(s): "%s" found in heading' % ", ".join(diff2schema)
     2096            return msg
     2097        if mode == "create":
     2098            required_keys = [layout.getIdUnprefixed(id)
     2099                                for id,widget in layout.objectItems()
     2100                                if widget.is_required]
     2101            if not set(required_keys).issubset(set(import_keys)):
     2102                diff2import = set(required_keys).difference(set(import_keys))
     2103                msg = 'required key(s): "%s" not found in heading' % ", ".join(diff2import)
     2104                return msg
     2105        #
     2106        # not_imported
     2107        #
     2108        not_imported_keys = import_keys + ["Error",]
     2109        not_imported_file = open(not_imported_fn,"a")
     2110        not_imported_csv_writer = csv.DictWriter(not_imported_file,
     2111                                                    not_imported_keys,
     2112                                                    extrasaction='ignore')
     2113        mapping = dict((k,k) for k in not_imported_keys)
     2114        not_imported_csv_writer.writerow(mapping)
     2115        not_imported = []
     2116        #
     2117        # imported
     2118        #
     2119        imported_keys = import_keys[:]
     2120        if 'id' not in imported_keys:
     2121            imported_keys.insert(0,"id")
     2122        imported_file = open(imported_fn,"a")
     2123        imported_csv_writer = csv.DictWriter(imported_file,
     2124                                             imported_keys,
     2125                                             extrasaction='ignore')
     2126        mapping = dict((k,k) for k in imported_keys)
     2127        imported_csv_writer.writerow(mapping)
     2128        imported = []
     2129        #
     2130        # pending
     2131        #
     2132        pending_records = {}
     2133        imports_pending = 0
     2134        total_pending = 0
     2135        format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
     2136        format_error = format + ',"%(Error)s"'
     2137        #format = '"%(id)s",'+ format
     2138        imported = []
     2139        if name in ('verdict','course_result',):
     2140            #global pending_records
     2141            pending_keys = imported_keys[:]
     2142            pending_keys += "Error",
     2143            pending_records = {}
     2144            if os.path.exists(pending_fn):
     2145                pending_imports_file = open(pending_fn)
     2146                pending_imports = csv.DictReader(pending_imports_file,
     2147                                                 fieldnames=pending_keys)
     2148                if pending_imports:
     2149                    pending_records = dict((row['id'],row) for row in pending_imports
     2150                                          if row['id'] != 'id')
     2151                pending_imports_file.close()
     2152            new_imports_pending = 0
     2153            pending_imported = []
     2154            for item in pending_records.values():
     2155                id,error = importer(item)
     2156                if error:
     2157                    continue
     2158                else:
     2159                    if item.has_key('Error'):
     2160                        del item['Error']
     2161                    imported.append(item)
     2162                    msg = format % item
     2163                    logger.info("imported from %(pending_fn)s %(msg)s" % vars())
     2164                    pending_imported += id,
     2165                    continue
     2166            total_imported = len(pending_imported)
     2167            logger.info("imported %d pending imports" % len(pending_imported))
     2168            for id in pending_imported:
     2169                del pending_records[id]
     2170            pending_imports_file = open(pending_fn,'w')
     2171            pending_csv_writer = csv.DictWriter(pending_imports_file,
     2172                                                pending_keys,
     2173                                                extrasaction='ignore')
     2174            mapping = dict((k,k) for k in pending_keys)
     2175            pending_csv_writer.writerow(mapping)
     2176        #
     2177        if pending_only:
     2178            items = []
     2179        else:
     2180            try:
     2181                items = csv.DictReader(open(import_source_fn,"rb"))
     2182            except:
     2183                msg = 'Error reading %s.csv' % filename
     2184                logger.error(msg)
     2185                return msg
     2186            not_imported = []
     2187        for item in items:
     2188            item = dict((k.strip(),l.strip()) for (k,l) in item.items())
     2189            if start:
     2190                start = False
     2191                adapters = [MappingStorageAdapter(schema, item)]
     2192                logger.info('%s starts import from %s.csv in %s mode with schema and layout %s' % (member,filename,mode,iname))
     2193            dm = DataModel(item, adapters,context=self)
     2194            ds = DataStructure(data=item,datamodel=dm)
     2195            error_string = ""
     2196            total += 1
     2197            error_count = 0
     2198            for k in import_keys:
     2199                if not validators[k](ds,mode=mode):
     2200                    if error_count:
     2201                        error_string += ' ++ '
     2202                    error_string += "%s: %s" % (k,self.translation_service(ds.getError(k),
     2203                                                                           ds.getErrorMapping(k)))
     2204                    error_count += 1
     2205            if error_string:
     2206                item['Error'] = error_string
     2207                not_imported.append(item)
     2208                total_not_imported += 1
     2209                continue
     2210            temp_item = item.copy()
     2211            temp_item.update(dm)
     2212            id,error = importer(temp_item)
     2213            if error:
     2214                item['Error'] = error
     2215                if id and id not in pending_records.keys():
     2216                    item['id'] = id
     2217                    pending_records[id] = item
     2218                    msg = format_error % item
     2219                    logger.info("%(id)s added to pending %(msg)s" % vars())
     2220                    new_imports_pending += 1
     2221                    continue
     2222                else:
     2223                    not_imported.append(item)
     2224                    total_not_imported += 1
     2225                    continue
     2226            item = temp_item
     2227            item['id'] = id
     2228            imported.append(item)
     2229            tr_count += 1
     2230            total_imported += 1
     2231            msg = format % item
     2232            logger.info("%(total_imported)d of %(total)d imported in %(mode)s mode, %(msg)s" % vars())
     2233            if total and not total % commit_after:
     2234                transaction.commit()
     2235                if len(imported) > 0:
     2236                    imported_csv_writer.writerows(imported)
     2237                    imported = []
     2238                if len(not_imported) > 0:
     2239                    not_imported_csv_writer.writerows(not_imported)
     2240                    not_imported = []
     2241                if len(pending_records) > 0:
     2242                    pending_csv_writer.writerows(pending_records.values())
     2243                    total_pending += len(pending_records)
     2244                    pending_records = {}
     2245                msg = '%d transactions committed\n' % (tr_count)
     2246                regs = []
     2247                logger.info(msg)
     2248                tr_count = 0
     2249        if len(imported) > 0:
     2250            imported_csv_writer.writerows(imported)
     2251        if len(not_imported) > 0:
     2252            not_imported_csv_writer.writerows(not_imported)
     2253        if len(pending_records) > 0:
     2254            pending_csv_writer.writerows(pending_records.values())
     2255            total_pending += len(pending_records)
     2256        msg = "Finished importing in %(mode)s mode from %(import_source_fn)s: " % vars()
     2257        msg += "%(total_imported)d imported, %(total_not_imported)d not imported " % vars()
     2258        if total_pending:
     2259            msg += "%(new_imports_pending)d pending added %(total_pending)d total pending in %(pending_fn)s " % vars()
     2260        msg += "(of total %(total)d)" % vars()
     2261        logger.info(msg)
     2262        return msg
     2263    ###)
     2264
     2265    def old_importData(self,filename,name,edit=False,bypass_queue_catalog=False):###(
    20222266        """load data from CSV values"""
    20232267        import transaction
Note: See TracChangeset for help on using the changeset viewer.