1
2
3
4 """
5 This module provides `Deposit_Receipt`, a convenient class for extracting information from the Deposit Receipts sent back by the
6 SWORD2-compliant server for many transactions.
7
8 #BETASWORD2URL
9 See Section 10. Deposit Receipt: http://sword-app.svn.sourceforge.net/viewvc/sword-app/spec/trunk/SWORDProfile.html?revision=HEAD#depositreceipt
10
11 """
12
13 from sword2_logging import logging
14 d_l = logging.getLogger(__name__)
15
16 from atom_objects import Category
17
18 from compatible_libs import etree
19 from utils import NS, get_text
20
22 - def __init__(self, xml_deposit_receipt=None, dom=None, response_headers={}, location=None, code=0):
23 """
24 `Deposit_Receipt` - provides convenience methods for extracting information from the Deposit Receipts sent back by the
25 SWORD2-compliant server for many transactions.
26
27 #BETASWORD2URL
28 See Section 10. Deposit Receipt: http://sword-app.svn.sourceforge.net/viewvc/sword-app/spec/trunk/SWORDProfile.html?revision=HEAD#depositreceipt
29
30 Transactions carried out by `sword2.Connection` will return a `Deposit_Receipt` object, if a deposit receipt document is sent back by the server.
31
32 Usage:
33
34 >>> from sword2 import Deposit_Receipt
35
36 .... get the XML text for a Deposit Receipt in the variable `doc`
37
38 # Parse the response:
39 >>> dr = Deposit_Receipt(xml_deposit_receipt = doc)
40
41 # Check that the response is parsable (valid XML) and is SWORD2-compliant
42 >>> assert dr.parsed == True
43 >>> assert dr.valid == True
44
45 Availible attributes:
46
47 Atom convenience attribs -- corresponds to (type of object that is held)
48 `self.title` -- <atom:title> (`str`)
49 `self.id` -- <id> (`str`)
50 `self.updated` -- <updated> (`str`)
51 `self.summary` -- <atom:summary> (`str`)
52 `self.categories` -- <category> (`list` of `sword2.Category`)
53
54 IRI/URIs
55 `self.edit` -- The Edit-IRI (`str`)
56 <link rel="edit">
57 `self.edit_media` -- The Edit-Media-IRI (`str`)
58 <link rel="edit-media">
59 `self.edit_media_feed` -- The Edit-Media-IRI [Atom Feed] (`str`)
60 <link rel="edit-media" type="application/atom+xml;type=feed">
61 `self.alternate` -- A link which, according to the spec, (`str`)
62 "points to the splash page of the item on the server"
63 `self.se_iri` -- The SWORD2 Edit IRI (SE-IRI), defined by (`str`)
64 <link rel="http://purl.org/net/sword/terms/add">
65 which MAY be the same as the Edit-IRI
66
67 `self.cont_iri` -- The Content-IRI (`str`)
68 eg `src` from <content type="application/zip" src="http://swordapp.org/cont-IRI/43/my_deposit"/>
69 `self.content` -- All Content-IRIs (`dict` with the src or Content-IRI as the key, with a `dict` of the other attributes as its value
70
71 `self.links` -- All links elements in a `dict`, with the 'rel' value being used as its key. The values of this are `list`s
72 with a `dict` of attributes for each item, corresponding to the information in a single <link> element.
73
74 SWORD2 links for "http://purl.org/net/sword/terms/originalDeposit" and "http://purl.org.net/sword/terms/derivedResource"
75 are to be found in `self.links`
76
77 eg
78 >>> dr.links.get("http://purl.org.net/sword/terms/derivedResource")
79 {'href': "....", 'type':'application/pdf'}
80
81
82 General metadata:
83 `self.metadata` -- Simple metadata access.
84 A `dict` where the keys are equivalent to the prefixed element names, with an underscore(_) replacing the colon (:)
85 eg "<dcterms:title>" in the deposit receipt would be accessible in this attribute, under
86 the key of 'dcterms_title'
87
88 eg
89 >>> dr.metadata.get("dcterms_title")
90 "The Origin of Species"
91
92 >>> dr.metadata.get("dcterms_madeupelement")
93 `None`
94
95 `self.packaging` -- sword:packaging elements declaring the formats that the Media Resource can be retrieved in (`list` of `str`)
96
97 `self.response_headers` -- The HTTP response headers that accompanied this receipt
98
99 `self.location` -- The location, if given (from HTTP Header: "Location: ....")
100 """
101 self.parsed = False
102 self.response_headers=response_headers
103 self.location = location
104 self.content = None
105 self.code = code
106 self.metadata = {}
107 self.links = {}
108 self.edit = None
109 self.edit_media = None
110 self.edit_media_feed = None
111 self.alternate = None
112 self.se_iri = None
113
114 self.title = None
115 self.id = None
116 self.updated = None
117 self.summary = None
118
119 self.packaging = []
120 self.categories = []
121 self.content = {}
122 self.cont_iri = None
123
124 if xml_deposit_receipt:
125 try:
126 self.dom = etree.fromstring(xml_deposit_receipt)
127 self.parsed = True
128 except Exception, e:
129 d_l.error("Was not able to parse the deposit receipt as XML.")
130 return
131 self.handle_metadata()
132 elif dom != None:
133 self.dom = dom
134 self.parsed = True
135 self.handle_metadata()
136
175
177 """Method that handles the intepreting of <atom:link> element information and placing it into the anticipated attributes."""
178
179 rel = e.attrib.get('rel', None)
180 if rel:
181 if rel == "edit":
182 self.edit = e.attrib.get('href', None)
183 elif rel == "edit-media":
184
185
186 if not ('type' in e.attrib.keys()):
187 self.edit_media = e.attrib.get('href', None)
188 elif e.attrib['type'] == "application/atom+xml;type=feed":
189 self.edit_media_feed = e.attrib.get('href', None)
190 elif rel == "http://purl.org/net/sword/terms/add":
191 self.se_iri = e.attrib.get('href', None)
192 elif rel == "alternate":
193 self.alternate = e.attrib.get('href', None)
194
195 attribs = {}
196 for k,v in e.attrib.iteritems():
197 if k != "rel":
198 attribs[k] = v
199 if self.links.has_key(rel):
200 self.links[rel].append(attribs)
201 else:
202 self.links[rel] = [attribs]
203
204
205 - def handle_content(self, e):
206 """Method to intepret the <atom:content> elements."""
207
208 if e.attrib.has_key("src"):
209 src = e.attrib['src']
210 info = dict(e.attrib).copy()
211 del info['src']
212 self.content[src] = info
213 self.cont_iri = src
214
216 """Convenience method for outputing the DOM as a (byte)string."""
217 return etree.tostring(self.dom)
218
220 """Method for producing a human-readable report about the information in this object, suitable
221 for CLI or other logging.
222
223 NB does not report all information, just key parts."""
224 _s = []
225 for k in sorted(self.metadata.keys()):
226 _s.append("%s: '%s'" % (k, self.metadata[k]))
227 if self.edit:
228 _s.append("Edit IRI: %s" % self.edit)
229 if self.edit_media:
230 _s.append("Edit-Media IRI: %s" % self.edit_media)
231 if self.se_iri:
232 _s.append("SWORD2 Add IRI: %s" % self.se_iri)
233 for c in self.categories:
234 _s.append(str(c))
235 if self.packaging:
236 _s.append("SWORD2 Package formats available: %s" % self.packaging)
237 if self.alternate:
238 _s.append("Alternate IRI: %s" % self.alternate)
239 for k, v in self.links.iteritems():
240 _s.append("Link rel:'%s' -- %s" % (k, v))
241 return "\n".join(_s)
242