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 from XSLForms.Resources.WebResources import \ 8 XSLFormsResource, input, output, resources, prepare_resources as xslforms_prepare_resources 9 import os 10 import libxml2dom 11 12 # Site map imports. 13 14 from WebStack.Resources.ResourceMap import MapResource 15 from WebStack.Resources.Selectors import EncodingSelector 16 from WebStack.Resources.Static import DirectoryResource 17 18 # Configuration setting. 19 20 encoding = "utf-8" 21 22 # Resource classes. 23 24 class AdminResource(XSLFormsResource): 25 26 "A resource providing administration facilities for job candidate profiles." 27 28 resource_dir = resources(__file__) 29 template_resources = { 30 "admin" : output("admin_template.xhtml") 31 } 32 init_resources = { 33 "admin" : input("admin_template.xhtml") 34 } 35 36 def __init__(self, repository): 37 self.repository = repository 38 39 def select_activity(self, trans, form): 40 form.set_activity("admin") 41 42 def create_document(self, trans, form): 43 is_new = XSLFormsResource.create_document(self, trans, form) 44 trans.get_attributes()["form_is_new"] = is_new 45 return is_new 46 47 def respond_to_input(self, trans, form): 48 49 # Get the "show" and "edit" resource paths. 50 # NOTE: These should be obtained from the site map. 51 52 vpath = trans.get_processed_virtual_path_info() 53 show_path = trans.get_path_without_info() + trans.update_path(vpath, "show") 54 edit_path = trans.get_path_without_info() + trans.update_path(vpath, "edit") 55 56 # Redirect if one of the CVs is to be shown or edited. 57 58 selectors = form.get_selectors() 59 if selectors.has_key("show"): 60 name = selectors["show"][0].getAttribute("name") 61 trans.redirect(trans.encode_path(show_path) + 62 "?name=%s" % trans.encode_path(name)) 63 elif selectors.has_key("edit"): 64 name = selectors["edit"][0].getAttribute("name") 65 trans.redirect(trans.encode_path(edit_path) + 66 "?name=%s" % trans.encode_path(name)) 67 68 # Add and remove elements according to the selectors found. 69 70 self.remove_elements(selectors.get("remove")) 71 self.add_elements(selectors.get("new"), "cv", "cvs") 72 73 def respond_to_document(self, trans, form): 74 75 admin = form.get_document() 76 77 # Synchronise the repository with the CVs found. 78 79 cvs = admin.xpath("/admin/cvs")[0] 80 for key in self.repository.keys(): 81 if key.startswith("candidate-"): 82 name = key[len("candidate-"):] 83 # NOTE: Apostrophes not quoted. 84 if not cvs.xpath("cv[@name = '%s']" % name): 85 if trans.get_attributes()["form_is_new"]: 86 cv = admin.createElement("cv") 87 cv.setAttribute("name", name) 88 cvs.appendChild(cv) 89 else: 90 del self.repository[key] 91 92 class CandidateUtils: 93 94 "Methods used by candidate-related resources." 95 96 def __init__(self, repository): 97 self.repository = repository 98 99 def select_activity(self, trans, form): 100 form.set_activity("candidate") 101 102 def create_document(self, trans, form): 103 documents = form.get_documents() 104 fields = trans.get_fields_from_path() 105 name = fields.get("name", [u"None"])[0] 106 107 # Ensure the presence of a document. 108 109 if documents.has_key("candidate"): 110 form.set_document(documents["candidate"]) 111 else: 112 if self.repository is None or not self.repository.has_key("candidate-%s" % name): 113 form.set_document(form.new_instance("candidate")) 114 else: 115 form.set_document(libxml2dom.parseString(self.repository["candidate-%s" % name])) 116 117 def init_document(self, trans, form): 118 status_xml = self.prepare_document("status") 119 XSLFormsResource.init_document(self, trans, form, references={"status" : status_xml}) 120 121 class DisplayResource(CandidateUtils, XSLFormsResource): 122 123 "A resource providing editing facilities for a job candidate profile." 124 125 resource_dir = resources(__file__) 126 template_resources = { 127 "candidate" : output("candidate_display_template.xhtml") 128 } 129 init_resources = { 130 "candidate" : input("candidate_template.xhtml") 131 } 132 document_resources = { 133 "status" : "candidate_status.xml" 134 } 135 136 class CandidateResource(CandidateUtils, XSLFormsResource): 137 138 "A resource providing editing facilities for a job candidate profile." 139 140 resource_dir = resources(__file__) 141 template_resources = { 142 "candidate" : output("candidate_template.xhtml") 143 } 144 init_resources = { 145 "candidate" : input("candidate_template.xhtml") 146 } 147 document_resources = { 148 "status" : "candidate_status.xml" 149 } 150 151 def respond_to_input(self, trans, form): 152 153 # Add and remove elements according to the selectors found. 154 155 selectors = form.get_selectors() 156 self.remove_elements(selectors.get("remove")) 157 self.add_elements(selectors.get("add-skill"), "skill", "skills") 158 self.add_elements(selectors.get("add-qualification"), "qualification", "qualifications") 159 self.add_elements(selectors.get("add-employment"), "employment", "experience") 160 161 def respond_to_document(self, trans, form): 162 163 candidate = form.get_document() 164 parameters = form.get_parameters() 165 fields = trans.get_fields_from_path() 166 name = fields.get("name", [u"None"])[0] 167 168 # Get the "show" resource path. 169 # NOTE: This should be obtained from the site map. 170 171 vpath = trans.get_processed_virtual_path_info() 172 show_path = trans.get_path_without_info() + trans.update_path(vpath, "show") 173 admin_path = trans.get_path_without_info() + trans.update_path(vpath, "") 174 175 # Redirect if the CV is to be shown. 176 177 if parameters.has_key("show"): 178 179 # Save the candidate information. 180 181 self.repository["candidate-%s" % name] = candidate.toString() 182 trans.redirect(trans.encode_path(show_path) + 183 "?name=%s" % trans.encode_path(name)) 184 185 # Redirect if the administration interface is to be used. 186 187 elif parameters.has_key("admin"): 188 189 # Save the candidate information. 190 191 self.repository["candidate-%s" % name] = candidate.toString() 192 trans.redirect(trans.encode_path(admin_path)) 193 194 # Site map initialisation. 195 196 def get_site(fsencoding=None, use_cwd=0): 197 198 "Return a simple Web site resource." 199 200 if use_cwd: 201 resource_dir = os.getcwd() 202 else: 203 resource_dir = resources(__file__) 204 repository = DirectoryRepository(os.path.join(resource_dir, "candidates"), fsencoding) 205 206 # Get the main resource and the directory used by the application. 207 208 candidate_resource = CandidateResource(repository) 209 display_resource = DisplayResource(repository) 210 admin_resource = AdminResource(repository) 211 212 # Make a simple Web site. 213 214 resource = MapResource({ 215 "edit" : candidate_resource, 216 "show" : display_resource, 217 "" : admin_resource 218 }) 219 220 return EncodingSelector(resource, encoding) 221 222 # Resource preparation ahead of time - useful for making installations. 223 224 def prepare_resources(): 225 for cls in [AdminResource, DisplayResource, CandidateResource]: 226 xslforms_prepare_resources(cls) 227 228 # vim: tabstop=4 expandtab shiftwidth=4