Changeset 17787 for main/waeup.kofa
- Timestamp:
- 15 May 2024, 06:42:58 (6 months ago)
- Location:
- main/waeup.kofa/trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/CHANGES.txt
r17782 r17787 5 5 ======================= 6 6 7 * Add `SessionConfigurationProcessor`. 8 9 * Add `ConfigurationContainerProcessor`. 10 7 11 * Add `ConfigurationContainerExporter`. 8 12 … … 17 21 * Mangle referees and school grades when exporting applicants. 18 22 19 * Add ` ConfigurationExporter`.23 * Add `SessionConfigurationExporter`. 20 24 21 25 * Do not allow to add a study level if course registration has ended. -
main/waeup.kofa/trunk/src/waeup/kofa/accesscodes/batching.py
r17761 r17787 50 50 factory_name = 'waeup.AccessCodeBatch' 51 51 52 mode = None53 54 52 def parentsExist(self, row, site): 55 53 return 'accesscodes' in site.keys() … … 107 105 location_fields = ['representation', 'batch_prefix', 'batch_num'] 108 106 factory_name = 'waeup.AccessCode' 109 110 mode = None111 107 112 108 @property -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/batching.py
r17774 r17787 106 106 factory_name = 'waeup.Applicant' 107 107 108 mode = None109 110 108 @property 111 109 def available_fields(self): -
main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py
r17784 r17787 1233 1233 # We don't need to edit next matric integers in the base package. 1234 1234 form_fields = grok.AutoFields(IConfigurationContainer).omit( 1235 'frontpage_dict',1236 1235 'next_matric_integer', 1237 1236 'next_matric_integer_2', -
main/waeup.kofa/trunk/src/waeup/kofa/configuration.py
r17782 r17787 39 39 grok.implements(IConfigurationContainer) 40 40 41 frontpage_dict = dict() 42 41 43 def addSessionConfiguration(self, sessionconfiguration): 42 44 """Add a session configuration object. … … 52 54 ConfigurationContainer = attrs_to_fields(ConfigurationContainer) 53 55 56 57 class ConfigurationContainerFactory(grok.GlobalUtility): 58 """A factory for configuration container. This factory is only needed 59 for import. 60 """ 61 grok.implements(IFactory) 62 grok.name(u'waeup.ConfigurationContainer') 63 64 def __call__(self, *args, **kw): 65 return ConfigurationContainer(*args, **kw) 66 67 def getInterfaces(self): 68 return implementedBy(ConfigurationContainer) 69 54 70 class SessionConfiguration(grok.Model): 55 71 """ … … 88 104 89 105 title = _(u'Base Configuration') 90 fields = tuple(sorted(iface_names(IConfigurationContainer))) + ('curr_stud_id',) 106 fields = tuple(sorted(iface_names( 107 IConfigurationContainer, omit=['captcha',]))) + ('curr_stud_id',) 91 108 92 109 def mangle_value(self, value, name, context=None): … … 106 123 return self.close_outfile(filepath, outfile) 107 124 108 class ConfigurationExporter(grok.GlobalUtility, ExporterBase):109 """The Configuration Exporter exports all configuration data. It iterates over all110 objects of the ``configuration`` container.125 class SessionConfigurationExporter(grok.GlobalUtility, ExporterBase): 126 """The Session Configuration Exporter exports all configuration data. 127 It iterates over all objects of the ``configuration`` container. 111 128 """ 112 129 grok.implements(ICSVExporter) 113 grok.name(' configurations')130 grok.name('sessionconfigurations') 114 131 115 132 title = _(u'Session Configurations') … … 128 145 129 146 def export_all(self, site, filepath=None): 130 """Export configurations into filepath as CSV data.147 """Export session configurations into filepath as CSV data. 131 148 132 149 If `filepath` is ``None``, a raw string with CSV data is returned. … … 135 152 return self.export(configurations.values(), filepath) 136 153 137 class ConfigurationProcessor(BatchProcessor): 138 """The Configuration Processor processes session configuration objects in 139 the ``configuration`` container. 154 class ConfigurationContainerProcessor(BatchProcessor): 155 """The Configuration Container Processor processes processes the 156 portal's base confoiguration data. This container exists in the portal. 157 Thus only the update method is allowed. 140 158 141 159 """ … … 143 161 grok.provides(IBatchProcessor) 144 162 grok.context(Interface) 145 util_name = 'configurationprocessor' 163 util_name = 'configurationcontainerupdater' 164 grok.name(util_name) 165 166 name = u'ConfigurationConainer Processor (update only)' 167 iface = IConfigurationContainer 168 factory_name = 'waeup.ConfigurationContainer' 169 170 @property 171 def available_fields(self): 172 return tuple( 173 sorted(iface_names( 174 IConfigurationContainer, 175 omit=['captcha',]))) + ('curr_stud_id',) 176 177 def parentsExist(self, row, site): 178 return True 179 180 def entryExists(self, row, site): 181 return True 182 183 def getParent(self, row, site): 184 return site 185 186 def getEntry(self, row, site): 187 return site['configuration'] 188 189 def updateEntry(self, obj, row, site, filename): 190 """Update obj to the values given in row. 191 """ 192 if 'curr_stud_id' in row: 193 studid = row.get('curr_stud_id') 194 site['students']._curr_stud_id = int(studid) 195 row.pop('curr_stud_id') 196 super(ConfigurationContainerProcessor, self).updateEntry( 197 obj, row, site, filename) 198 return 199 200 class SessionConfigurationProcessor(BatchProcessor): 201 """The (Session) Configuration Processor processes session configuration 202 objects in the ``configuration`` container. 203 """ 204 grok.implements(IBatchProcessor) 205 grok.provides(IBatchProcessor) 206 grok.context(Interface) 207 util_name = 'sessionconfigurationprocessor' 146 208 grok.name(util_name) 147 209 … … 149 211 iface = ISessionConfiguration 150 212 factory_name = 'waeup.SessionConfiguration' 151 152 mode = None153 213 154 214 def parentsExist(self, row, site): … … 181 241 pass 182 242 243 -
main/waeup.kofa/trunk/src/waeup/kofa/doctests/batchprocessing_browser.txt
r17772 r17787 105 105 'CertificateCourse Processor', 106 106 'Certificate Processor', 107 ' SessionConfiguration Processor',107 'ConfigurationConainer Processor (update only)', 108 108 'Course Processor', 109 109 'CourseTicket Processor', … … 115 115 'Public PDF Document Processor', 116 116 'Public REST Document Processor', 117 'SessionConfiguration Processor', 117 118 'Student Processor', 118 119 'StudentStudyCourse Processor', -
main/waeup.kofa/trunk/src/waeup/kofa/documents/batching.py
r17763 r17787 67 67 68 68 factory_name = None 69 70 mode = None71 69 72 70 @property -
main/waeup.kofa/trunk/src/waeup/kofa/hostels/batching.py
r17313 r17787 45 45 location_fields = ['hostel_id',] 46 46 factory_name = 'waeup.Hostel' 47 48 mode = None49 47 50 48 def parentsExist(self, row, site): … … 98 96 location_fields = ['hostel_id', 'bed_id'] 99 97 factory_name = None 100 101 mode = None102 98 103 99 @property -
main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py
r17376 r17787 724 724 """ 725 725 726 frontpage_dict = Attribute('Language translation dictionary with values in HTML format') 727 726 728 name = schema.TextLine( 727 729 title = _(u'Name of University'), … … 741 743 default = default_html_frontpage, 742 744 constraint=validate_html, 743 )744 745 frontpage_dict = schema.Dict(746 title = u'Content as language dictionary with values in html format',747 required = False,748 default = {},749 745 ) 750 746 -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_webservices.py
r16393 r17787 1111 1111 self.assertEqual(xmlout, RESPONSE_XML) 1112 1112 return 1113 1114 def test_get_student_info(self): 1115 server = ServerProxy('http://mgr:mgrpw@localhost/app') 1116 self.setup_student(self.student) 1117 result = server.get_student_info('123') 1118 self.assertEqual(result, 1119 ['Anna Tester', 'CERT1', '1234', 'aa@aa.ng']) 1120 REQUEST_XML = """\ 1121 <?xml version="1.0"?> 1122 <methodCall> 1123 <methodName>get_student_info</methodName> 1124 <params> 1125 <param> 1126 <value><string>K1000000</string></value> 1127 </param> 1128 </params> 1129 </methodCall>""" 1130 RESPONSE_XML = """\ 1131 <?xml version='1.0'?> 1132 <methodResponse> 1133 <params> 1134 <param> 1135 <value><array><data> 1136 <value><string>Anna Tester</string></value> 1137 <value><string>CERT1</string></value> 1138 <value><string>1234</string></value> 1139 <value><string>aa@aa.ng</string></value> 1140 </data></array></value> 1141 </param> 1142 </params> 1143 </methodResponse> 1144 """ 1145 xmlout = self.XMLRPC_post(REQUEST_XML) 1146 self.assertEqual(xmlout, RESPONSE_XML) 1147 return 1148 1149 def test_get_student_base_data(self): 1150 server = ServerProxy('http://mgr:mgrpw@localhost/app') 1151 result = server.get_student_base_data() 1152 self.assertEqual(result, 1153 [{'entry_mode': None, 1154 'reg_number': '123', 1155 'firstname': 'Anna', 1156 'middlename': None, 1157 'current_session': 2004, 1158 'entry_session': 2004, 1159 'certcode': 'CERT1', 1160 'state': 'created', 1161 'student_id': 'K1000000', 1162 'faccode': 'fac1', 1163 'lastname': 'Tester', 1164 'matric_number': '234', 1165 'depcode': 'dep1'}]) 1166 REQUEST_XML = """\ 1167 <?xml version="1.0"?> 1168 <methodCall> 1169 <methodName>get_student_base_data</methodName> 1170 <params> 1171 </params> 1172 </methodCall>""" 1173 RESPONSE_XML = """\ 1174 <?xml version='1.0'?> 1175 <methodResponse> 1176 <params> 1177 <param> 1178 <value><array><data> 1179 <value><struct> 1180 <member> 1181 <name>entry_mode</name> 1182 <value><nil/></value></member> 1183 <member> 1184 <name>reg_number</name> 1185 <value><string>123</string></value> 1186 </member> 1187 <member> 1188 <name>firstname</name> 1189 <value><string>Anna</string></value> 1190 </member> 1191 <member> 1192 <name>middlename</name> 1193 <value><nil/></value></member> 1194 <member> 1195 <name>current_session</name> 1196 <value><int>2004</int></value> 1197 </member> 1198 <member> 1199 <name>entry_session</name> 1200 <value><int>2004</int></value> 1201 </member> 1202 <member> 1203 <name>certcode</name> 1204 <value><string>CERT1</string></value> 1205 </member> 1206 <member> 1207 <name>matric_number</name> 1208 <value><string>234</string></value> 1209 </member> 1210 <member> 1211 <name>state</name> 1212 <value><string>created</string></value> 1213 </member> 1214 <member> 1215 <name>faccode</name> 1216 <value><string>fac1</string></value> 1217 </member> 1218 <member> 1219 <name>lastname</name> 1220 <value><string>Tester</string></value> 1221 </member> 1222 <member> 1223 <name>student_id</name> 1224 <value><string>K1000000</string></value> 1225 </member> 1226 <member> 1227 <name>depcode</name> 1228 <value><string>dep1</string></value> 1229 </member> 1230 </struct></value> 1231 </data></array></value> 1232 </param> 1233 </params> 1234 </methodResponse> 1235 """ 1236 xmlout = self.XMLRPC_post(REQUEST_XML) 1237 self.assertEqual(xmlout, RESPONSE_XML) 1238 return -
main/waeup.kofa/trunk/src/waeup/kofa/students/webservices.py
r16393 r17787 533 533 ) 534 534 return hitlist 535 536 # Data requested by the WAeUP team 537 538 @grok.require('waeup.xmlrpc') 539 def get_student_base_data(self, 540 current_session=None, current_level=None, certcode=None, 541 current_mode=None, depcode=None, p_session=None): 542 """Returns bursary data of a subset of students. 543 """ 544 if not current_session: 545 current_session = None 546 if not current_level: 547 current_level = None 548 if not depcode: 549 depcode = None 550 if not certcode: 551 certcode = None 552 if not current_mode: 553 current_mode = None 554 hitlist = [] 555 cat = queryUtility(ICatalog, name='students_catalog') 556 results = cat.searchResults( 557 current_session=(current_session, current_session), 558 current_level=(current_level, current_level), 559 certcode=(certcode, certcode), 560 current_mode=(current_mode, current_mode), 561 depcode=(depcode, depcode), 562 ) 563 for student in results: 564 hitlist.append(dict( 565 student_id=student.student_id, 566 matric_number=student.matric_number, 567 reg_number=student.reg_number, 568 firstname=student.firstname, 569 middlename=student.middlename, 570 lastname=student.lastname, 571 state=student.state, 572 current_session=student.current_session, 573 entry_session=student.entry_session, 574 entry_mode=student.entry_mode, 575 faccode=student.faccode, 576 depcode=student.depcode, 577 certcode=student.certcode, 578 ) 579 ) 580 return hitlist -
main/waeup.kofa/trunk/src/waeup/kofa/tests/test_configuration.py
r17782 r17787 30 30 from waeup.kofa.configuration import ( 31 31 ConfigurationContainer, SessionConfiguration, SessionConfigurationFactory, 32 ConfigurationContainerExporter, ConfigurationExporter) 33 from waeup.kofa.interfaces import(ICSVExporter, 32 ConfigurationContainerExporter, SessionConfigurationExporter, 33 ConfigurationContainerProcessor, SessionConfigurationProcessor) 34 from waeup.kofa.interfaces import(ICSVExporter, IBatchProcessor, 34 35 IConfigurationContainer, ISessionConfiguration, ISessionConfigurationAdd) 35 36 … … 124 125 result = open(self.outfile, 'rb').read() 125 126 self.assertTrue( 126 'acronym,ca ptcha,carry_over,current_academic_session,email_admin,'127 'email_subject,export_disabled_message,frontpage, frontpage_dict,'127 'acronym,carry_over,current_academic_session,email_admin,' 128 'email_subject,export_disabled_message,frontpage,' 128 129 'maintmode_enabled_by,name,name_admin,next_matric_integer,' 129 130 'next_matric_integer_2,next_matric_integer_3,' 130 131 'next_matric_integer_4,smtp_mailer,curr_stud_id\r\n' 131 'WAeUP.Kofa, No captcha,0,,contact@waeup.org,Kofa Contact,,'132 'WAeUP.Kofa,0,,contact@waeup.org,Kofa Contact,,' 132 133 '"<h1>Welcome to WAeUP.Kofa\n<br>' in result 133 134 ) … … 138 139 def test_ifaces(self): 139 140 # make sure we fullfill interface contracts 140 obj = ConfigurationExporter()141 obj = SessionConfigurationExporter() 141 142 verify.verifyObject(ICSVExporter, obj) 142 verify.verifyClass(ICSVExporter, ConfigurationExporter)143 verify.verifyClass(ICSVExporter, SessionConfigurationExporter) 143 144 return 144 145 145 146 def test_get_as_utility(self): 146 147 # we can get a faculty exporter as utility 147 result = queryUtility(ICSVExporter, name=" configurations")148 result = queryUtility(ICSVExporter, name="sessionconfigurations") 148 149 self.assertTrue(result is not None) 149 150 return … … 154 155 self.sessionconfig.clearance_fee = 3000.6 155 156 self.app['configuration'].addSessionConfiguration(self.sessionconfig) 156 exporter = ConfigurationExporter()157 exporter = SessionConfigurationExporter() 157 158 exporter.export_all(self.app, self.outfile) 158 159 result = open(self.outfile, 'rb').read() … … 164 165 ) 165 166 return 167 168 BASECONFIG_SAMPLE_DATA = open( 169 os.path.join(os.path.dirname(__file__), 'sample_baseconfig_data.csv'), 170 'rb').read() 171 172 BASECONFIG_HEADER_FIELDS = BASECONFIG_SAMPLE_DATA.split( 173 '\n')[0].split(',') 174 175 class BaseConfigurationProcessorTests(ConfigurationImportExportSetup): 176 177 layer = FunctionalLayer 178 179 def setUp(self): 180 super(BaseConfigurationProcessorTests, self).setUp() 181 self.processor = ConfigurationContainerProcessor() 182 183 def test_interface(self): 184 # Make sure we fulfill the interface contracts. 185 assert verify.verifyObject(IBatchProcessor, self.processor) is True 186 assert verify.verifyClass( 187 IBatchProcessor, ConfigurationContainerProcessor) is True 188 189 def test_import(self): 190 self.csv_file = os.path.join( 191 self.workdir, 'sample_baseconfig_data.csv') 192 open(self.csv_file, 'wb').write(BASECONFIG_SAMPLE_DATA) 193 num, num_warns, fin_file, fail_file = self.processor.doImport( 194 self.csv_file, BASECONFIG_HEADER_FIELDS,'update') 195 self.assertEqual(num_warns,0) 196 configcontainer = self.processor.getEntry(dict(), self.app) 197 self.assertEqual(configcontainer.frontpage, 'Hello World') 198 199 SESSIONCONFIG_SAMPLE_DATA = open( 200 os.path.join(os.path.dirname(__file__), 'sample_sessionconfig_data.csv'), 201 'rb').read() 202 203 SESSIONCONFIG_HEADER_FIELDS = SESSIONCONFIG_SAMPLE_DATA.split( 204 '\n')[0].split(',') 205 206 class SessionConfigurationProcessorTests(ConfigurationImportExportSetup): 207 208 layer = FunctionalLayer 209 210 def setUp(self): 211 super(SessionConfigurationProcessorTests, self).setUp() 212 self.processor = SessionConfigurationProcessor() 213 214 def test_interface(self): 215 # Make sure we fulfill the interface contracts. 216 assert verify.verifyObject(IBatchProcessor, self.processor) is True 217 assert verify.verifyClass( 218 IBatchProcessor, SessionConfigurationProcessor) is True 219 220 def test_import(self): 221 self.csv_file = os.path.join( 222 self.workdir, 'sample_sessionconfig_data.csv') 223 open(self.csv_file, 'wb').write(SESSIONCONFIG_SAMPLE_DATA) 224 num, num_warns, fin_file, fail_file = self.processor.doImport( 225 self.csv_file, SESSIONCONFIG_HEADER_FIELDS,'create') 226 self.assertEqual(num_warns,0) 227 sessionconfig = self.processor.getEntry({'academic_session':'2017'}, self.app) 228 self.assertEqual(sessionconfig.payment_disabled[0], 'sf_all') 229 230 -
main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py
r14724 r17787 65 65 location_fields = ['code',] 66 66 factory_name = 'waeup.Faculty' 67 68 mode = None69 67 70 68 def parentsExist(self, row, site): … … 192 190 factory_name = 'waeup.Department' 193 191 194 mode = None195 196 192 def parentsExist(self, row, site): 197 193 if not 'faculties' in site.keys(): … … 244 240 location_fields = ['code'] 245 241 factory_name = 'waeup.Certificate' 246 247 mode = None248 242 249 243 @property … … 328 322 location_fields = ['code'] 329 323 factory_name = 'waeup.Course' 330 331 mode = None332 324 333 325 def getParent(self, row, site): … … 384 376 factory_name = 'waeup.CertificateCourse' 385 377 386 mode = None387 388 378 def parentsExist(self, row, site): 389 379 if not 'faculties' in site.keys(): -
main/waeup.kofa/trunk/src/waeup/kofa/utils/converters.py
r17764 r17787 242 242 # Omit known dictionaries since there is no widget available 243 243 # for dictionary schema fields 244 self.default_form_fields = form.Fields(iface).omit('description_dict') 244 self.default_form_fields = form.Fields(iface).omit( 245 'description_dict', 'frontpage_dict') 245 246 return 246 247
Note: See TracChangeset for help on using the changeset viewer.