1 | ''' |
---|
2 | Class representing the pylons controller for trackback functionality. This allows: |
---|
3 | |
---|
4 | i) commenting on metadata |
---|
5 | ii) referencing of metadata |
---|
6 | |
---|
7 | NB, info on TrackBack available from: |
---|
8 | |
---|
9 | http://www.sixapart.com/pronet/docs/trackback_spec |
---|
10 | |
---|
11 | @author: C Byrom, Tessella Feb 2009 |
---|
12 | ''' |
---|
13 | from milk_server.lib.base import * |
---|
14 | from milk_server.models.ndgdoc import NDGDoc |
---|
15 | from ndg.common.src.models.ndgObject import ndgObject |
---|
16 | import ndg.common.src.clients.xmldb.eXist.dbconstants as dc |
---|
17 | from ndg.common.src.lib.mailer import mailHandler |
---|
18 | |
---|
19 | class TrackbackController(BaseController): |
---|
20 | ''' |
---|
21 | Provides the pylons controller for recieving trackbacks to NDG documents |
---|
22 | ''' |
---|
23 | def __setup(self,uri): |
---|
24 | ''' |
---|
25 | Common setup stuff for all the actions on this controller |
---|
26 | @param uri: ndgURI associated with current doc being viewed |
---|
27 | ''' |
---|
28 | logging.info("Setting up TrackbackController") |
---|
29 | self.cf = request.environ['ndgConfig'] |
---|
30 | try: |
---|
31 | self.uri=ndgObject(uri, config = self.cf) |
---|
32 | except ValueError,e: |
---|
33 | return e |
---|
34 | |
---|
35 | self.inputs = request.params |
---|
36 | |
---|
37 | self.ndgDoc = NDGDoc(ndgURI = uri, config = self.cf) |
---|
38 | logging.info("TrackbackController set up") |
---|
39 | return 0 |
---|
40 | |
---|
41 | |
---|
42 | def ping(self, uri): |
---|
43 | ''' |
---|
44 | This is the default trackback receipt method. When a doc is referenced |
---|
45 | from a TrackBack enabled site, this method should be invoked, via a |
---|
46 | TrackBack ping, to notify that it has been referenced. Log the reference |
---|
47 | by sending a mail to the trackback recipient set in the config file and |
---|
48 | adding an entry to the citation feed. |
---|
49 | ( Note we haven't implemented whitelisting yet ) |
---|
50 | @param uri: ndgURI associated with the doc being pinged by trackback |
---|
51 | ''' |
---|
52 | logging.info("Trackback ping called - notifying trackback recipient + feed of citation") |
---|
53 | err = 0 |
---|
54 | status=self.__setup(uri) |
---|
55 | |
---|
56 | # lookup referenced doc - to ensure it exists and get extra info to add |
---|
57 | # to citation messages |
---|
58 | self.ndgDoc.setupDocumentModel() |
---|
59 | payload = "" |
---|
60 | if self.ndgDoc.status: |
---|
61 | payload = '<trackback><uri>%s</uri><title>%s</title></trackback>' %(self.ndgDoc.docModel.atomBrowseURL, |
---|
62 | self.ndgDoc.name) |
---|
63 | else: |
---|
64 | err = "Could not find document, '%s', to reference in trackback" %uri |
---|
65 | |
---|
66 | server = self.cf.get('DEFAULT', 'mailserver') |
---|
67 | if server is None: |
---|
68 | err = 'Server not configured for trackback (no mail server)' |
---|
69 | |
---|
70 | recipient=self.cf.get('DEFAULT', 'tbrecipient') |
---|
71 | if recipient is None: |
---|
72 | err = 'Server not configured for trackback (no recipient)' |
---|
73 | |
---|
74 | body='Citation Trackback for %s\n\n\n%s'% (uri, payload) |
---|
75 | name='CitationTrackbackFor_%s.xml'%uri |
---|
76 | |
---|
77 | if err != 0: |
---|
78 | c.message = err |
---|
79 | c.err = 1 |
---|
80 | else: |
---|
81 | logging.info("Sending notification mail to '%s'" %recipient) |
---|
82 | status, message = mailHandler([recipient,], body, body, |
---|
83 | xmlAttachments = [(payload, name),], |
---|
84 | server = server) |
---|
85 | if status: |
---|
86 | c.err = 0 |
---|
87 | else: |
---|
88 | c.err = 1 |
---|
89 | c.message = 'Unable to forward trackback to designated recipient [%s]' %message |
---|
90 | |
---|
91 | # lastly, add to citation feed |
---|
92 | logging.info("Mail sent - now add data to the citations feed") |
---|
93 | g.validator._atomClient.feedClient.createGenericFeedEntry(name, payload, |
---|
94 | dc.CITATIONS_COLLECTION_PATH) |
---|
95 | |
---|
96 | response.headers['content-type'] = 'text/xml' |
---|
97 | |
---|
98 | logging.info("Trackback logged - now sending receipt") |
---|
99 | return render('genshi', 'trackback/trackback',format='xml') |
---|
100 | |
---|
101 | |
---|
102 | def getTrackBackInfo(self, uri, name): |
---|
103 | ''' |
---|
104 | Get the trackback info for the specified uri and name |
---|
105 | @param uri: ndgURI representing doc |
---|
106 | @param name: title of doc |
---|
107 | @return rdf element representing trackback info |
---|
108 | ''' |
---|
109 | s='''<!-- |
---|
110 | <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
---|
111 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
---|
112 | xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> |
---|
113 | <rdf:Description |
---|
114 | rdf:about="%s" |
---|
115 | dc:identifier="%s" |
---|
116 | dc:title="%s" |
---|
117 | trackback:ping="%s" /> |
---|
118 | </rdf:RDF> |
---|
119 | -->'''%(uri,g.server+h.url_for(),name, |
---|
120 | g.server+h.url_for(controller="trackback/trackback", action="ping")) |
---|
121 | return s |
---|
122 | |
---|
123 | |
---|
124 | |
---|
125 | def askCorrect(self,uri): |
---|
126 | ''' |
---|
127 | Provide a form (ajaxaciously) so that a user can correct a metadata record |
---|
128 | ''' |
---|
129 | logging.info("Called askCorrect - to render a corrections input form") |
---|
130 | status=self.__setup(uri) |
---|
131 | c.uri=self.uri |
---|
132 | |
---|
133 | if status: |
---|
134 | return response.write(status) |
---|
135 | |
---|
136 | try: |
---|
137 | html = render("genshi", 'trackback/correct',fragment=True) |
---|
138 | except Exception, e: |
---|
139 | logging.error("Error experienced whilst rendering 'correct' template: %s" %e) |
---|
140 | |
---|
141 | logging.info("- retrieved info - now rendering form") |
---|
142 | return html |
---|
143 | |
---|
144 | |
---|
145 | def correct(self, uri): |
---|
146 | ''' |
---|
147 | Receive a correction form to update a record and post it to the holder |
---|
148 | ''' |
---|
149 | logging.info("Submitting correction info - this will be mailed to metadata " + \ |
---|
150 | "maintainer + added to the corrections feed") |
---|
151 | status=self.__setup(uri) |
---|
152 | if 'ndgSec' not in session: |
---|
153 | c.xml = 'Error - user not currently logged in. Please login before submitting user comments.' |
---|
154 | logging.error(c.xml) |
---|
155 | return render('kid', 'error') |
---|
156 | |
---|
157 | body = 'Metadata Change Request for %s' %uri |
---|
158 | payload = '<Change><uri>%s</uri><from>%s</from><Contents>%s</Contents></Change>' \ |
---|
159 | %(self.inputs['Identifier'],self.inputs['Submitter'],self.inputs['Comment']) |
---|
160 | name = 'ChangeRequestFor_%s.xml' %uri |
---|
161 | maintainer = self.cf.get('DEFAULT','metadataMaintainer') |
---|
162 | |
---|
163 | logging.info("Mailing corrections info to %s" %maintainer) |
---|
164 | status,message = mailHandler([maintainer,], |
---|
165 | body,body,xmlAttachments=[(payload,name),], |
---|
166 | server=self.cf.get('DEFAULT','mailserver')) |
---|
167 | if status: |
---|
168 | result = 'Your comments have been sent to the metadata maintainer and added to corrections feed for the metatadata database.' |
---|
169 | else: |
---|
170 | result = message |
---|
171 | |
---|
172 | c.xml = result |
---|
173 | logging.info("- now add these to the corrections feed") |
---|
174 | # add the maintainer info |
---|
175 | body += " - for metadata maintainer, '%s'" %maintainer |
---|
176 | g.validator._atomClient.feedClient.createGenericFeedEntry(body, payload, |
---|
177 | dc.CORRECTIONS_COLLECTION_PATH) |
---|
178 | |
---|
179 | g.correctionPosted = result |
---|
180 | h.redirect_to(h.url_for(controller = 'browse/retrieve', action='view', \ |
---|
181 | uri = uri)) |
---|
182 | |
---|