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