Mercurial > hg > ZopePubmanConnector
annotate zopePubmanConnector.py @ 14:d92decb037d6
bugs in publ
author | dwinter |
---|---|
date | Fri, 31 May 2013 11:40:00 +0200 |
parents | 43849c9cc08b |
children | ca3084877394 |
rev | line source |
---|---|
0 | 1 # -*- coding: utf-8 -*- |
2 | |
3 #Verbindet Zope mit pubman. | |
4 | |
5 | |
6 from OFS.SimpleItem import SimpleItem | |
7 from Products.PageTemplates.PageTemplateFile import PageTemplateFile | |
8 import os.path | |
9 | |
10 from Globals import package_home | |
11 import httplib2 | |
12 import xml.etree.ElementTree as ET | |
1 | 13 import logging |
9 | 14 import time |
10 | 15 import unicodedata |
6 | 16 |
17 cacheFolder ="/var/tmp/.cacheWWW" | |
18 | |
14 | 19 ns = {'escidocMetadataProfile':"http://escidoc.mpg.de/metadataprofile/schema/0.1/", |
20 'escidocMetadataRecords':"http://www.escidoc.de/schemas/metadatarecords/0.4", | |
21 'dc':'http://purl.org/dc/elements/1.1/', | |
22 'escidocComponents':'http://www.escidoc.de/schemas/components/0.8', | |
23 'escidocItem':'http://www.escidoc.de/schemas/item/0.8' | |
24 } | |
25 | |
26 | |
27 | |
0 | 28 def zptFile(self, path, orphaned=False): |
29 """returns a page template file from the product""" | |
30 if orphaned: | |
31 # unusual case | |
32 pt=PageTemplateFile(os.path.join(package_home(globals()), path)) | |
33 else: | |
34 | |
35 pt=PageTemplateFile(os.path.join(package_home(globals()), path)).__of__(self) | |
36 return pt | |
37 | |
38 class ZopePubmanConnector(SimpleItem): | |
39 | |
40 | |
41 connectorString="http://pubman.mpiwg-berlin.mpg.de/search/SearchAndExport?" | |
42 | |
43 | |
44 meta_type="ZopePubmanConnector" | |
45 | |
46 manage_options= ({'label':'Main Config','action': 'changeMain'},) + SimpleItem.manage_options | |
47 | |
48 def __init__(self,id,title,pubmanURL): | |
49 self.id=id | |
50 self.title=title | |
51 self.pubmanURL=pubmanURL #URL einer pubman instance bzw. einer collection, falls nicht die default collection benutzt werden soll | |
52 | |
53 | |
54 | |
55 def changeMain(self,pubmanURL=None,title=None,REQUEST=None,RESPONSE=None): | |
56 """change main settings""" | |
57 if pubmanURL: | |
58 self.pubmanURL=pubmanURL | |
59 self.title=title | |
60 | |
61 if RESPONSE is not None: | |
62 RESPONSE.redirect('manage_main') | |
63 | |
64 | |
65 else: | |
66 pt=zptFile(self, 'zpt/ChangeZopePubmanConnector.zpt') | |
67 return pt() | |
68 | |
69 | |
2 | 70 def getPublications(self,personID,limit=None,publicationType=None): |
0 | 71 """get all publications der personID""" |
6 | 72 h = httplib2.Http(cacheFolder) |
1 | 73 |
74 | |
2 | 75 |
76 if publicationType is None: | |
11 | 77 # cn = self.connectorString+"cqlQuery=escidoc.any-identifier=%22"+personID+"%22&" |
78 cn = self.connectorString+"cqlQuery=escidoc.publication.creator.person.identifier=%22"+personID+"%22&" | |
2 | 79 else: |
11 | 80 #cn = self.connectorString+"cqlQuery=escidoc.any-identifier=%22"+personID+"%22" |
13
43849c9cc08b
Incomplete - # 74: More Link auf den pers?nlichne Homepages
dwinter
parents:
12
diff
changeset
|
81 cn = self.connectorString+"cqlQuery=%28escidoc.publication.creator.person.identifier=%22"+personID+"%22%29" |
43849c9cc08b
Incomplete - # 74: More Link auf den pers?nlichne Homepages
dwinter
parents:
12
diff
changeset
|
82 cn +="%20and%28%20escidoc.publication.type=%22"+publicationType+"%22%29&" |
2 | 83 |
84 cn +="exportFormat=APA&outputFormat=snippet&language=all&sortKeys=escidoc.any-dates&sortOrder=descending" | |
85 if limit: | |
86 cn+="&maximumRecords=%s"%limit | |
1 | 87 |
2 | 88 logging.debug(cn) |
89 resp, content = h.request(cn) | |
90 | |
3 | 91 |
2 | 92 |
0 | 93 ET.register_namespace("dcterms", "http://purl.org/dc/terms/") |
94 | |
95 root = ET.fromstring(content) | |
96 | |
2 | 97 #<escidocItem:item objid="escidoc:630782" |
98 | |
0 | 99 citationxpath=".//{http://purl.org/dc/terms/}bibliographicCitation" |
100 | |
2 | 101 objxpath=".//{http://www.escidoc.de/schemas/item/0.8}item" |
14 | 102 |
103 | |
104 | |
2 | 105 citations=root.findall(objxpath) |
14 | 106 logging.debug(len(citations)) |
0 | 107 ret=[] |
108 for citation in citations: | |
2 | 109 objId = citation.get('objid') |
14 | 110 |
2 | 111 text = citation.find(citationxpath) |
112 | |
14 | 113 |
114 | |
115 | |
116 | |
117 idTermPath =""".//escidocMetadataRecords:md-records/escidocMetadataRecords:md-record/escidocMetadataProfile:publication/dc:identifier""" | |
118 #idTermPath =".//{http://purl.org/dc/elements/1.1/}identifier" | |
119 | |
120 idterms = citation.findall(idTermPath,ns) | |
121 | |
122 linksIdentifier=[] | |
123 linksLocator=[] | |
124 | |
125 | |
126 bookID = None | |
127 | |
128 | |
129 for idterm in idterms: | |
130 if idterm.get("{http://www.w3.org/2001/XMLSchema-instance}type",'') in ['eterms:OTHER','eidt:OTHER']: ##suche nach bookID | |
131 logging.debug("zopePubmanConnector: %s"%idterm.text) | |
132 checkID =idterm.text.lstrip().rstrip() | |
133 if checkID.startswith("MPIWG-Book:"): | |
134 bookID = checkID | |
135 break | |
136 elif idterm.get("{http://www.w3.org/2001/XMLSchema-instance}type",'') in ['eterms:URI','eidt:URI']: | |
137 linksIdentifier.append(idterm.text.lstrip().rstrip()) | |
138 | |
139 | |
140 | |
141 | |
142 componentsPath =""".//escidocComponents:components[1]""" | |
143 | |
144 components=citation.findall(componentsPath,ns); | |
145 | |
146 for component in components: | |
147 cnt = component.find(".//escidocComponents:content",ns) | |
148 if cnt is not None: | |
149 link="" | |
150 title="" | |
151 type="" | |
152 for name,value in cnt.items(): | |
153 if name.endswith("href"): | |
154 link=value | |
155 elif name.endswith("title"): | |
156 title=value | |
157 elif name.endswith("storage"): | |
158 type=value | |
159 | |
160 linksLocator.append((title,link,type)) | |
161 | |
162 | |
163 | |
164 | |
165 ret.append((objId,text.text,bookID,linksIdentifier,linksLocator)) | |
0 | 166 |
167 | |
168 | |
169 return ret | |
170 | |
2 | 171 |
5 | 172 def search(self,values={},exact=False,limit=None,contexts=None): |
2 | 173 """search pubman |
174 @values map mit field->value | |
175 @return map mit escidocId -> XML-formatted snippeds | |
176 """ | |
177 | |
178 fieldToEscidoc={"title":"escidoc.any-title", | |
179 "author":"escidoc.publication.any.publication-creator-names", | |
10 | 180 "any":"escidoc.metadata"} |
2 | 181 |
182 | |
183 cn = self.connectorString+"cqlQuery=%s&" | |
184 cn +="exportFormat=APA&outputFormat=snippet&language=all&sortKeys=escidoc.any-dates&sortOrder=descending" | |
185 | |
5 | 186 if limit: |
187 cn+="&maximumRecords=%s"%limit | |
2 | 188 |
189 querys = [] | |
190 for field in values.keys(): | |
191 | |
192 searchField = fieldToEscidoc.get(field,None) | |
193 if searchField is None: | |
194 logging.debug("search, don't know field: %s"%field) | |
195 continue | |
196 | |
197 value = values[field] | |
10 | 198 try: |
199 value=unicodedata.normalize('NFKD', value).encode('ASCII', 'ignore') | |
200 except: | |
201 value=unicodedata.normalize('NFKD', value.decode('utf-8')).encode('ASCII', 'ignore') | |
2 | 202 if value == '': |
203 continue | |
204 logging.debug("%s=%s"%(field,value)) | |
205 if not exact: | |
206 value=value+"*" | |
207 | |
208 querys.append("%s=%%22%s%%22"%(searchField,value)) | |
209 | |
10 | 210 query="%20AND%20".join(querys) |
5 | 211 |
212 if contexts: # einscbraenken auf contexte | |
213 | |
214 if isinstance(contexts, str): | |
215 contexts=[contexts] | |
216 | |
217 ctxquerys=[] | |
218 for context in contexts: | |
219 ctxquerys.append("escidoc.context.objid=%%22%s%%22"%(context)) | |
220 | |
10 | 221 ctxquery="%20OR%20".join(ctxquerys) |
5 | 222 |
223 if query!="": | |
10 | 224 query=query+"AND%%20(%s)"%ctxquery |
5 | 225 else: |
226 query="(%s)"%ctxquery | |
227 | |
12 | 228 try: |
229 h = httplib2.Http(cacheFolder) | |
230 logging.debug("search: "+cn%query) | |
231 resp, content = h.request(cn%query) | |
232 except: | |
233 logging.error("Unable to get data from PubMan!") | |
234 return {} | |
2 | 235 |
236 ET.register_namespace("dcterms", "http://purl.org/dc/terms/") | |
237 | |
3 | 238 try: |
239 root = ET.fromstring(content) | |
240 except: | |
241 logging.error("Couldn't parse content of:%s"%(cn%query)) | |
242 return {} | |
2 | 243 #<escidocItem:item objid="escidoc:630782" |
244 | |
245 citationxpath=".//{http://purl.org/dc/terms/}bibliographicCitation" | |
246 | |
247 objxpath=".//{http://www.escidoc.de/schemas/item/0.8}item" | |
248 citations=root.findall(objxpath) | |
249 | |
250 ret={} | |
251 for citation in citations: | |
252 objId = citation.get('objid') | |
253 text = citation.find(citationxpath) | |
254 ret[objId]=text.text | |
255 | |
256 return ret | |
257 | |
11 | 258 |
259 def getEntriesFromPubman(self,escidocids): | |
2 | 260 |
11 | 261 doctypes={} |
262 for escidocid in escidocids: | |
263 | |
264 txt, type = self.getEntryFromPubman(escidocid.escidocid, True) | |
265 | |
266 if not doctypes.has_key(type): | |
267 doctypes[type]=[] | |
268 | |
269 doctypes[type].append((escidocid.escidocid,txt)) | |
270 | |
271 | |
272 return doctypes | |
273 | |
274 | |
275 def getEntryFromPubman(self,escidocid,extendedData=None): | |
4 | 276 """get one entry""" |
277 | |
14 | 278 |
279 | |
3 | 280 escidocid=escidocid.lstrip().strip() |
6 | 281 h = httplib2.Http(cacheFolder) |
2 | 282 cn = self.connectorString+"cqlQuery=escidoc.objid=%s&" |
283 cn +="exportFormat=APA&outputFormat=snippet&language=all&sortKeys=escidoc.any-dates&sortOrder=descending" | |
284 | |
285 resp, content = h.request(cn%escidocid) | |
286 ET.register_namespace("dcterms", "http://purl.org/dc/terms/") | |
3 | 287 logging.debug(cn%escidocid) |
4 | 288 |
2 | 289 root = ET.fromstring(content) |
290 | |
291 | |
292 citationxpath=".//{http://purl.org/dc/terms/}bibliographicCitation" | |
293 | |
14 | 294 itempath = ".//escidocItem:item" |
295 | |
296 item = root.find(itempath,ns) #get item | |
297 | |
298 citation=item.find(citationxpath,ns) | |
299 | |
300 | |
301 if citation is not None and extendedData is not None: | |
302 | |
303 linksIdentifier=[] | |
304 linksLocator=[] | |
305 | |
2 | 306 |
11 | 307 |
14 | 308 #get identifier |
309 idTermPath =""".//escidocMetadataRecords:md-records/escidocMetadataRecords:md-record/escidocMetadataProfile:publication/dc:identifier""" | |
310 #idTermPath =".//{http://purl.org/dc/elements/1.1/}identifier" | |
311 | |
312 idterms = item.findall(idTermPath,ns) | |
313 | |
314 bookID = None | |
315 logging.debug("zopePubmanConnector: %s"%idterms) | |
316 for idterm in idterms: | |
317 | |
318 if idterm.get("{http://www.w3.org/2001/XMLSchema-instance}type",'') in ['eterms:OTHER','eidt:OTHER']: ##suche nach bookID | |
319 logging.debug("zopePubmanConnector: %s"%idterm.text) | |
320 checkID =idterm.text.lstrip().rstrip() | |
321 if checkID.startswith("MPIWG-Book:"): | |
322 bookID = checkID | |
323 break | |
324 elif idterm.get("{http://www.w3.org/2001/XMLSchema-instance}type",'') in ['eterms:URI','eidt:URI']: | |
325 linksIdentifier.append(idterm.text.lstrip().rstrip()) | |
326 | |
327 | |
328 #get files and locators | |
329 componentsPath =""".//escidocComponents:components[1]""" | |
330 | |
331 components=item.findall(componentsPath,ns); | |
332 | |
333 for component in components: | |
334 cnt = component.find(".//escidocComponents:content",ns) | |
335 if cnt is not None: | |
336 link="" | |
337 title="" | |
338 type="" | |
339 for name,value in cnt.items(): | |
340 if name.endswith("href"): | |
341 link=value | |
342 elif name.endswith("title"): | |
343 title=value | |
344 elif name.endswith("storage"): | |
345 type=value | |
346 | |
347 linksLocator.append((title,link,type)) | |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | |
356 | |
11 | 357 path = ".//escidocMetadataRecords:md-records/escidocMetadataRecords:md-record/escidocMetadataProfile:publication" |
14 | 358 publicationTag= item.find(path,ns); |
359 | |
360 return citation.text,publicationTag.get('type'),bookID,linksIdentifier,linksLocator | |
11 | 361 |
2 | 362 if citation is not None: |
363 | |
364 return citation.text | |
11 | 365 |
366 return "",'' | |
2 | 367 |
0 | 368 def pubmanConnectorURL(self): |
369 return self.connectorString | |
4 | 370 |
371 | |
10 | 372 def getPublicationsFromContext(self,context,limit=None,publicationType=None,search=None): |
7 | 373 """gibt alle publicationen des context, jeweils als tupel ("escidoc:id",METADATEN) |
374 | |
375 METADATEN ist hierbei eine Map mit : | |
376 "citation" --> citation in der APA formatierung | |
377 "volume" --> volume | |
378 "link" --> dowloadlink | |
379 "abstracts" --> map mit deu/eng für den abstrakt | |
380 "authors" --> [(NACHNAME,VORNAME]),..] | |
381 "title"--> title | |
382 "year" --> issued | |
383 """ | |
6 | 384 h = httplib2.Http(cacheFolder) |
4 | 385 |
386 if publicationType is None: | |
10 | 387 cn = self.connectorString+"cqlQuery=(escidoc.context.objid=%22"+context+"%22" |
4 | 388 #cn = self.connectorString+"cqlQuery=escidoc.objid=%22"+"escidoc:643455"+"%22&" |
389 else: | |
10 | 390 cn = self.connectorString+"cqlQuery=(escidoc.context.objid=%22"+context+"%22" |
391 cn +="%20and%20escidoc.publication.type=%22"+publicationType+"%22" | |
4 | 392 |
10 | 393 if search is not None and search != "": |
394 try: | |
395 search = unicodedata.normalize('NFKD', search).encode('ASCII', 'ignore') | |
396 except: | |
397 search = unicodedata.normalize('NFKD', search.decode('utf-8')).encode('ASCII', 'ignore') | |
398 cn+="%20and%20escidoc.metadata="+search+"" | |
399 | |
400 | |
401 cn +=")&exportFormat=APA&outputFormat=snippet&language=all&sortKeys=escidoc.any-dates&sortOrder=descending" | |
4 | 402 if limit: |
403 cn+="&maximumRecords=%s"%limit | |
404 | |
9 | 405 startTime = time.time() |
12 | 406 try: |
407 logging.debug("getPublicationsFromContext: getting %s"%cn) | |
408 resp, content = h.request(cn) | |
409 logging.debug("getPublicationsFromContext: got data in %ss"%(time.time()-startTime)) | |
4 | 410 |
12 | 411 ET.register_namespace("dcterms", "http://purl.org/dc/terms/") |
4 | 412 |
12 | 413 root = ET.fromstring(content) |
414 | |
415 except Exception, e: | |
416 logging.error("Unable to read and parse data! %s"%e) | |
417 return [] | |
418 | |
4 | 419 #<escidocItem:item objid="escidoc:630782" |
420 | |
421 citationxpath=".//{http://purl.org/dc/terms/}bibliographicCitation" | |
422 abstractpath=".//{http://purl.org/dc/terms/}abstract" | |
6 | 423 issuedpath=".//{http://purl.org/dc/terms/}issued" |
424 | |
425 creatorpath=".//{http://escidoc.mpg.de/metadataprofile/schema/0.1/publication}creator/{http://escidoc.mpg.de/metadataprofile/schema/0.1/types}person" | |
426 familyNamepath=".//{http://escidoc.mpg.de/metadataprofile/schema/0.1/types}family-name" | |
427 givenNamepath=".//{http://escidoc.mpg.de/metadataprofile/schema/0.1/types}given-name" | |
428 | |
429 | |
430 titlepath=".//{http://purl.org/dc/elements/1.1/}title" | |
4 | 431 |
432 objxpath=".//{http://www.escidoc.de/schemas/item/0.8}item" | |
433 srcpath=".//{http://escidoc.mpg.de/metadataprofile/schema/0.1/publication}source" | |
434 volumepath=".//{http://escidoc.mpg.de/metadataprofile/schema/0.1/types}volume" | |
435 | |
436 #linkspath=""".//{http://www.escidoc.de/schemas/components/0.8}component/{http://www.escidoc.de/schemas/components/0.8}content[@storage="internal-managed"]""" | |
437 linkspath=""".//{http://www.escidoc.de/schemas/components/0.8}component/{http://www.escidoc.de/schemas/components/0.8}content[@storage="external-url"]""" | |
438 #linkspath=".//{http://www.escidoc.de/schemas/components/0.8}component/{http://www.escidoc.de/schemas/components/0.8}content" | |
439 citations=root.findall(objxpath) | |
440 | |
441 ret=[] | |
442 for citation in citations: | |
443 objId = citation.get('objid') | |
444 | |
445 text = citation.find(citationxpath) | |
446 | |
447 #Get volume = preprintID | |
448 # <publication:source type="series"> | |
449 # <dc:title>Max-Planck-Institut für Wissenschaftsgeschichte : Preprint</dc:title> | |
450 # <escidoc:volume>437</escidoc:volume> | |
451 | |
452 src= citation.find(srcpath) | |
453 vol = src.find(volumepath) | |
454 | |
455 #get link to fulltext | |
456 #<escidocComponents:component objid="escidoc:644183"> | |
457 #<escidocComponents:properties> | |
458 # <prop:creation-date>2013-04-29T09:00:01.100Z</prop:creation-date> | |
459 # <prop:valid-status>valid</prop:valid-status> | |
460 # <prop:visibility>public</prop:visibility> | |
461 # <prop:content-category>pre-print</prop:content-category> | |
462 # <prop:file-name>P437.PDF</prop:file-name> | |
463 # <prop:mime-type>application/pdf</prop:mime-type> | |
464 # <prop:checksum>d0ccdc62d6707d934e60e9839ffe30bf</prop:checksum> | |
465 # <prop:checksum-algorithm>MD5</prop:checksum-algorithm> | |
466 #</escidocComponents:properties> | |
467 #<escidocComponents:content xlink:type="simple" xlink:title="P437.PDF" storage="internal-managed" | |
468 # xlink:href="http://pubman.mpiwg-berlin.mpg.de/pubman/item/escidoc:643686:3/component/escidoc:644183/P437.PDF"/> | |
469 # | |
470 | |
471 src= citation.find(linkspath) | |
472 if src is not None: | |
473 | |
474 link=src.get("{http://www.w3.org/1999/xlink}href") | |
475 #logging.debug(src.attrib) | |
476 | |
477 else: | |
478 link ="" | |
479 | |
480 #<dcterms:abstract xml:lang="deu">Dieser Preprint versammelt eine Auswahl von Beiträgen zum Symposium zu Ehren von Hans-Jörg Rheinbergers 65. Geburtstag. Es fand am 24.1.2011 im Max-Planck-Institute für Wissenschaftsgeschichte statt und brachte Freunde, Studenten und Kollegen von Hans-Jörg Rheinberger zusammen.</dcterms:abstract> | |
481 #<dcterms:abstract xml:lang="eng">In this preprint, a selection of contributions to the symposium in honor of Hans-Jörg Rheinberger’s 65th birthday is published. It took place on January 24, 2011 at the Max-Planck-Institute for the History of Science and assembled friends, students and colleagues of Hans-Jörg Rheinberger.</dcterms:abstract> | |
482 | |
483 abstracts = citation.findall(abstractpath) | |
484 | |
485 abstractTexts={} | |
486 for abstract in abstracts: | |
487 | |
488 lang = abstract.get("{http://www.w3.org/XML/1998/namespace}lang") | |
489 abstractTexts[lang]=abstract.text | |
6 | 490 |
491 authorsTags = citation.findall(creatorpath) | |
492 | |
493 authors=[] | |
494 for author in authorsTags: | |
495 | |
496 gn= author.find(givenNamepath).text | |
497 fn= author.find(familyNamepath).text | |
498 | |
499 authors.append((fn,gn)) | |
500 | |
8
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
501 titleTag = citation.find(titlepath) |
6 | 502 |
503 if titleTag is not None: | |
504 title = titleTag.text | |
505 else: | |
506 title="" | |
507 | |
508 issuedTag = citation.find(issuedpath) | |
509 | |
510 if issuedTag is not None: | |
511 issued = issuedTag.text | |
512 else: | |
513 issued="" | |
4 | 514 |
8
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
515 item = {"id":objId, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
516 "citation":text.text, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
517 "volume":vol.text, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
518 "link":link, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
519 "abstracts":abstractTexts, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
520 "authors":authors, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
521 "title":title, |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
522 "year":issued} |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
523 |
ddd7e357e518
changed getPreprints to getPublicationsFromContext. returns simple list.
casties
parents:
7
diff
changeset
|
524 ret.append(item) |
9 | 525 |
526 logging.debug("getPublicationsFromContext: done in %ss"%(time.time()-startTime)) | |
4 | 527 return ret |
528 | |
529 | |
530 | |
0 | 531 |
532 def manage_addZopePubmanConnectorForm(self): | |
533 """Form for external Links""" | |
534 pt=zptFile(self, 'zpt/AddZopePubmanConnector.zpt') | |
535 return pt() | |
536 | |
537 | |
538 def manage_addZopePubmanConnector(self,id,title,pubmanURL,RESPONSE=None): | |
539 """Add an external Link""" | |
540 | |
541 newObj=ZopePubmanConnector(id,title,pubmanURL) | |
542 | |
543 self._setObject(id,newObj) | |
544 | |
545 if RESPONSE is not None: | |
546 RESPONSE.redirect('manage_main') | |
547 |