1 #!/usr/bin/env python 2 3 "A job candidate editing application." 4 5 import WebStack.Generic 6 from WebStack.Repositories.Directory import DirectoryRepository 7 import XSLForms.Resources.WebResources 8 import XSLForms.Utils 9 import os 10 import libxml2dom 11 12 # Site map imports. 13 14 from WebStack.Resources.ResourceMap import MapResource 15 from WebStack.Resources.Static import DirectoryResource 16 17 # Resource classes. 18 19 class AdminResource(XSLForms.Resources.WebResources.XSLFormsResource): 20 21 "A resource providing administration facilities for job candidate profiles." 22 23 resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") 24 encoding = "utf-8" 25 template_resources = { 26 "admin" : ("admin_template.xhtml", "admin_output.xsl") 27 } 28 init_resources = { 29 "admin" : ("admin_template.xhtml", "admin_input.xsl") 30 } 31 32 def respond_to_form(self, trans, form): 33 34 """ 35 Respond to a request having the given transaction 'trans' and the given 36 'form' information. 37 """ 38 39 parameters = form.get_parameters() 40 documents = form.get_documents() 41 42 # Get the "show" and "edit" resource paths. 43 # NOTE: These should be obtained from the site map. 44 45 parts = trans.get_processed_virtual_path_info(self.path_encoding).split("/") 46 show_path = "/".join(parts[:-1] + ["show"]) 47 edit_path = "/".join(parts[:-1] + ["edit"]) 48 49 # Ensure the presence of a document. 50 51 form_is_new = 0 52 if documents.has_key("admin"): 53 admin = documents["admin"] 54 else: 55 admin = form.new_instance("admin") 56 form_is_new = 1 57 58 # Redirect if one of the CVs is to be shown or edited. 59 60 selectors = form.get_selectors() 61 if selectors.has_key("show"): 62 name = selectors["show"][0].getAttribute("name") 63 self._redirect(trans, show_path + "?name=%s" % name.encode(self.path_encoding)) 64 elif selectors.has_key("edit"): 65 name = selectors["edit"][0].getAttribute("name") 66 self._redirect(trans, edit_path + "?name=%s" % name.encode(self.path_encoding)) 67 68 # Add and remove elements according to the selectors found. 69 70 XSLForms.Utils.remove_elements(selectors.get("remove")) 71 XSLForms.Utils.add_elements(selectors.get("new"), "cv", "cvs") 72 73 # Transform, adding enumerations/ranges. 74 75 init_xsl = self.prepare_initialiser("admin") 76 admin = self.get_result([init_xsl], admin) 77 78 # Synchronise the session with the CVs found. 79 80 cvs = admin.xpath("/admin/cvs")[0] 81 session = DirectoryRepository(os.path.join(self.resource_dir, "candidates")) 82 #session = trans.get_session() 83 for key in session.keys(): 84 if key.startswith("candidate-"): 85 name = key[len("candidate-"):] 86 # NOTE: Apostrophes not quoted. 87 if not cvs.xpath("cv[@name = '%s']" % name): 88 if form_is_new: 89 cv = admin.createElement("cv") 90 cv.setAttribute("name", name) 91 cvs.appendChild(cv) 92 else: 93 del session[key] 94 95 # Start the response. 96 97 trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding)) 98 99 # Ensure that an output stylesheet exists. 100 101 trans_xsl = self.prepare_output("admin") 102 stylesheet_parameters = {} 103 104 # Complete the response. 105 106 self.send_output(trans, [trans_xsl], admin, stylesheet_parameters) 107 108 def _redirect(self, trans, path): 109 trans.set_response_code(302) 110 trans.set_header_value("Location", path) 111 raise WebStack.Generic.EndOfResponse 112 113 class DisplayResource(XSLForms.Resources.WebResources.XSLFormsResource): 114 115 "A resource providing editing facilities for a job candidate profile." 116 117 resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") 118 encoding = "utf-8" 119 template_resources = { 120 "candidate_display" : ("candidate_display_template.xhtml", "candidate_display_output.xsl") 121 } 122 init_resources = { 123 "candidate" : ("candidate_template.xhtml", "candidate_input.xsl") 124 } 125 document_resources = { 126 "status" : "candidate_status.xml" 127 } 128 129 def respond_to_form(self, trans, form): 130 131 """ 132 Respond to a request having the given transaction 'trans' and the given 133 'form' information. 134 """ 135 136 parameters = form.get_parameters() 137 documents = form.get_documents() 138 fields = trans.get_fields_from_path() 139 name = fields.get("name", [u"None"])[0] 140 141 # Ensure the presence of a document. 142 143 if documents.has_key("candidate"): 144 candidate = documents["candidate"] 145 else: 146 session = DirectoryRepository(os.path.join(self.resource_dir, "candidates")) 147 #session = trans.get_session(create=0) 148 if session is None or not session.has_key("candidate-%s" % name.encode("utf-8")): 149 candidate = form.new_instance("candidate") 150 else: 151 candidate = libxml2dom.parseString(session["candidate-%s" % name.encode("utf-8")]) 152 153 # Transform, adding enumerations/ranges. 154 155 init_xsl = self.prepare_initialiser("candidate") 156 status_xml = self.prepare_document("status") 157 candidate = self.get_result([init_xsl], candidate, references={"status" : status_xml}) 158 159 # Start the response. 160 161 trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding)) 162 163 # Ensure that an output stylesheet exists. 164 # Handle the "show" operation. 165 166 trans_xsl = self.prepare_output("candidate_display") 167 stylesheet_parameters = {} 168 169 # Complete the response. 170 171 self.send_output(trans, [trans_xsl], candidate, stylesheet_parameters) 172 173 class CandidateResource(XSLForms.Resources.WebResources.XSLFormsResource): 174 175 "A resource providing editing facilities for a job candidate profile." 176 177 resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") 178 encoding = "utf-8" 179 template_resources = { 180 "candidate" : ("candidate_template.xhtml", "candidate_output.xsl") 181 } 182 init_resources = { 183 "candidate" : ("candidate_template.xhtml", "candidate_input.xsl") 184 } 185 document_resources = { 186 "status" : "candidate_status.xml" 187 } 188 189 def respond_to_form(self, trans, form): 190 191 """ 192 Respond to a request having the given transaction 'trans' and the given 193 'form' information. 194 """ 195 196 parameters = form.get_parameters() 197 documents = form.get_documents() 198 fields = trans.get_fields_from_path() 199 name = fields.get("name", [u"None"])[0] 200 201 # Get the "show" resource path. 202 # NOTE: This should be obtained from the site map. 203 204 parts = trans.get_processed_virtual_path_info(self.path_encoding).split("/") 205 show_path = "/".join(parts[:-1] + ["show"]) 206 admin_path = "/".join(parts[:-1] + [""]) 207 208 # Ensure the presence of a document. 209 210 if documents.has_key("candidate"): 211 candidate = documents["candidate"] 212 else: 213 session = DirectoryRepository(os.path.join(self.resource_dir, "candidates")) 214 #session = trans.get_session(create=0) 215 if session is None or not session.has_key("candidate-%s" % name.encode("utf-8")): 216 candidate = form.new_instance("candidate") 217 else: 218 candidate = libxml2dom.parseString(session["candidate-%s" % name.encode("utf-8")]) 219 220 # Add and remove elements according to the selectors found. 221 222 selectors = form.get_selectors() 223 XSLForms.Utils.remove_elements(selectors.get("remove")) 224 XSLForms.Utils.add_elements(selectors.get("add-skill"), "skill", "skills") 225 XSLForms.Utils.add_elements(selectors.get("add-qualification"), "qualification", "qualifications") 226 XSLForms.Utils.add_elements(selectors.get("add-employment"), "employment", "experience") 227 228 # Transform, adding enumerations/ranges. 229 230 init_xsl = self.prepare_initialiser("candidate") 231 status_xml = self.prepare_document("status") 232 candidate = self.get_result([init_xsl], candidate, references={"status" : status_xml}) 233 234 # Redirect if the CV is to be shown. 235 236 if parameters.has_key("show"): 237 238 # Save the candidate information. 239 240 session = DirectoryRepository(os.path.join(self.resource_dir, "candidates")) 241 #session = trans.get_session() 242 session["candidate-%s" % name.encode("utf-8")] = candidate.toString() 243 self._redirect(trans, show_path + "?name=%s" % name.encode(self.path_encoding)) 244 245 # Redirect if the administration interface is to be used. 246 247 elif parameters.has_key("admin"): 248 249 # Save the candidate information. 250 251 session = DirectoryRepository(os.path.join(self.resource_dir, "candidates")) 252 #session = trans.get_session() 253 session["candidate-%s" % name.encode("utf-8")] = candidate.toString() 254 self._redirect(trans, admin_path) 255 256 # Start the response. 257 258 trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding)) 259 260 # Ensure that an output stylesheet exists. 261 262 trans_xsl = self.prepare_output("candidate") 263 stylesheet_parameters = {} 264 265 # Complete the response. 266 267 self.send_output(trans, [trans_xsl], candidate, stylesheet_parameters) 268 269 def _redirect(self, trans, path): 270 trans.set_response_code(302) 271 trans.set_header_value("Location", path) 272 raise WebStack.Generic.EndOfResponse 273 274 # Site map initialisation. 275 276 def get_site(): 277 278 "Return a simple Web site resource." 279 280 # Get the main resource and the directory used by the application. 281 282 candidate_resource = CandidateResource() 283 display_resource = DisplayResource() 284 admin_resource = AdminResource() 285 directory = candidate_resource.resource_dir 286 287 # Make a simple Web site. 288 289 resource = MapResource({ 290 "edit" : candidate_resource, 291 "show" : display_resource, 292 "" : admin_resource 293 }) 294 295 return resource 296 297 # vim: tabstop=4 expandtab shiftwidth=4