1: from OFS.Folder import Folder
2: from OFS.Image import File
3: from OFS.Image import cookId
4: from Globals import DTMLFile, InitializeClass,package_home
5: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
6: from AccessControl import getSecurityManager
7: from Products.PageTemplates.PageTemplate import PageTemplate
8: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
9: from AccessControl import ClassSecurityInfo
10: from difflib import Differ
11: from pprint import pprint
12: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
13:
14: try:
15: from Products.ImageArchive.ImageArchive import manage_AddImageZogiLib
16: except:
17: print "no images"
18:
19:
20: from threading import Thread
21: import shutil
22: import tempfile
23: import os.path
24: import urllib
25:
26: import time
27: try:
28: from Products.ECHO_content.ECHO_collection import ECHO_basis
29: except:
30: print "ECHO Elements not imported"
31: class ECHO_basis:
32: """leer"""
33: manage_options=()
34:
35:
36: def sortv(x,y):
37: return cmp(x[0],y[0])
38:
39: tdir = "/tmp/downloadVersionedFiles"
40:
41: class generateDownloadZip:
42: """generateDownloadSet"""
43:
44: def __init__(self,folderObject,url):
45: """init downloadzip"""
46: self.folder=folderObject
47: self.done=None
48: self.response=""
49: self.url=url
50:
51: def __call__(self):
52: """call generate download zip"""
53: storeTempDir=tempfile.tempdir
54: tempfile.tempdir=tdir
55:
56: tmpPath=tempfile.mktemp()
57: tmpZip=tempfile.mktemp()+".gtz"
58: tmpFn=os.path.split(tmpZip)[1]
59:
60: if not os.path.exists(tempfile.tempdir):
61: os.mkdir(tempfile.tempdir)
62:
63: if not os.path.exists(tmpPath):
64: os.mkdir(tmpPath)
65:
66: tempfile.tempdir=storeTempDir
67: self.response="<h3>1. step: getting the files</h3>"
68:
69: for files in self.folder.ZopeFind(self.folder,obj_metatypes=['versionedFile']):
70: lastV=files[1].getLastVersion()
71: self.response+=str("<p>Get File: %s<br>\n"%lastV.title)
72:
73: savePath=os.path.join(tmpPath,lastV.title)
74: fh=file(savePath,"w")
75: fh.write(lastV.data)
76: fh.close()
77:
78: self.response+="<h3>2. step: creating the downloadable file</h3>"
79: self.response+="<p>Create gtar<br>"
80: self.response+="<p>This can take a while....<br>\n"
81:
82: fh=os.popen2("tar zcvf %s %s/*"%(tmpZip,tmpPath),1)[1]
83: self.response+="<br>"
84: for c in fh.read():
85: self.response+=c
86: if c==")":
87: self.response+="<br>\n"
88:
89:
90:
91:
92: shutil.rmtree(tmpPath)
93:
94: self.response+="<p>finished<br>\n"
95:
96: len=os.stat(tmpZip)[6]
97: downloadUrl=self.url+"/downloadSet"
98: self.response+="""<h1><a href="downloadSet?fn=%s">Click here for download ( %i Byte)</a></h1>\n"""%(tmpFn,len)
99: self.response+="""<p>The file you receive is a tar (gnutar) compressed file, after unpacking you will find a new folder <emph>tmp</emph> where the files are stored in.</p>"""
100: self.response+="""<p>The file will be stored for a while, you can download it later, the URL is:</p>
101: <p><a href="downloadSet?fn=%s">%s?fn=%s</a></h1>\n"""%(tmpFn,downloadUrl,tmpFn)
102:
103: self.done=True
104:
105:
106: def getResult(self):
107: """get result"""
108: return self.response
109:
110: def isDone(self):
111: if self.done:
112: return True
113: else:
114: return False
115:
116:
117: class versionedFileFolder(Folder,ECHO_basis):
118: """Folder with versioned files"""
119:
120:
121: meta_type = "versionedFileFolder"
122:
123: security= ClassSecurityInfo()
124: security.declareProtected('AUTHENTICATED_USER','addFileForm')
125: filesMetaType=['versionedFile']
126: if ECHO_basis:
127: optTMP= Folder.manage_options+ECHO_basis.manage_options
128: else:
129: optTMP= Folder.manage_options
130:
131: manage_options =optTMP+(
132: {'label':'Generate Index.html','action':'generateIndexHTML'},
133: {'label':'Generate Image Index.html','action':'generateIndexHTML_image'},
134: {'label':'Generate history_template.html','action':'generateHistoryHTML'},
135: {'label':'Import Folder','action':'impor<olderForm'},
136: {'label':'Export Folder','action':'exportFolder'},
137: {'label':'Position of version number','action':'changeHistoryFileNamesForm'},
138: )
139:
140:
141: def changeHistoryFileNamesForm(self):
142: """change position of version num"""
143: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeHistoryFileNamesForm.zpt')).__of__(self)
144: return pt()
145:
146:
147: def changeHistoryFileNames(self,positionVersionNum="front",RESPONSE=None):
148: """change position of version num"""
149:
150:
151:
152: versions=self.ZopeFind(self,obj_metatypes=['versionedFileObject'],search_sub=1)
153:
154: if not (getattr(self,'positionVersionNum','front')==positionVersionNum):
155:
156: for version in versions:
157:
158: if positionVersionNum=="front":
159:
160: titleTmp=os.path.splitext(version[1].title)
161: titleTmp2="_".join(titleTmp[0].split("_")[0:-1])
162: if len(titleTmp)>1:
163: id=titleTmp[0].split("_")[-1]+"_"+titleTmp2+"."+titleTmp[1]
164: else:
165: id=titleTmp[0].split("_")[-1]+"_"+titleTmp2
166:
167: else:
168: titleTmp="_".join(version[1].getId().split("_")[1:])
169: tmp=os.path.splitext(titleTmp)
170: if len(tmp)>1:
171: id=tmp[0]+"_"+version[1].getId().split("_")[0]+tmp[1]
172: else:
173: id=tmp[0]+"_"+version[1].getId().split("_")[0]
174:
175:
176:
177: version[1].aq_parent.manage_renameObjects(ids=[version[1].getId()],new_ids=[id])
178: version[1].title=id
179:
180:
181: self.positionVersionNum=positionVersionNum
182: if RESPONSE:
183: RESPONSE.redirect("manage_main")
184:
185:
186:
187: def importFolderForm(self):
188: """form fuer folder import"""
189: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importFolderForm.zpt')).__of__(self)
190: return pt()
191:
192: def importFolder(self,path,comment="",author=None,lockedBy=None,RESPONSE=None):
193: """importiere inhalt eines folders"""
194:
195: for fileName in os.listdir(path):
196: if os.path.isfile(os.path.join(path,fileName)):
197: manage_addVersionedFile(self,fileName,'','')
198: id=fileName
199: ob=self._getOb(fileName)
200: ob.title=id
201: file2=file(os.path.join(path,fileName))
202:
203: obj=ob.manage_addVersionedFileObject(id,comment,author,file2,content_type='')
204:
205: if RESPONSE:
206: RESPONSE.redirect(self.REQUEST['URL1'])
207:
208: zipThreads={}
209: zipThreads2={}
210:
211: def refreshTxt(self):
212: """txt fuer refresh"""
213: tn=self.REQUEST.SESSION['threadName']
214: return """ 2;url=%s?repeat=%s """%(self.absolute_url()+"/exportFolder",tn)
215:
216: def exportFolder(self,repeat=None):
217: """exportiert alle akutellen files des folders"""
218: threadName=repeat
219:
220: downloadZip=generateDownloadZip(self,self.absolute_url())
221: downloadZip()
222: return downloadZip.getResult()
223: ## if not threadName or threadName=="":
224: ## threadStart=generateDownloadZip(self,self.absolute_url())
225: ## thread=Thread(target=threadStart)
226:
227: ## thread.start()
228:
229:
230: ## self.zipThreads[thread.getName()[0:]]=threadStart
231: ## self.zipThreads2[thread.getName()[0:]]=thread
232: ## self.REQUEST.SESSION['threadName']=thread.getName()[0:]
233: ## wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['zip_wait_template'])
234: ## if wait_template:
235: ## return wait_template[0][1]()
236: ## pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','zip_wait.zpt')).__of__(self)
237: ## return pt()
238:
239: ## else:
240: ## self.REQUEST.SESSION['threadName']=threadName
241:
242: ## if (self.zipThreads[threadName].getResult()==None):
243:
244: ## wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
245: ## if wait_template:
246: ## return wait_template[0][1]()
247:
248: ## pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','zip_wait.zpt')).__of__(self)
249: ## return pt()
250: ## else:
251: ## if self.zipThreads[threadName].isDone():
252: ## self.REQUEST.SESSION['result']=self.zipThreads[threadName].getResult()
253: ## self.zipThreads2[threadName].join()
254: ## del(self.zipThreads2[threadName])
255: ## del(self.zipThreads[threadName])
256: ## pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','zip_result.zpt')).__of__(self)
257: ## return pt()
258:
259: ## else:
260: ## self.REQUEST.SESSION['result']=self.zipThreads[threadName].getResult()
261: ## self.REQUEST.SESSION['threadName']=threadName
262: ## pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','zip_wait_result.zpt')).__of__(self)
263: ## return pt()
264:
265: def downloadSet(self,fn):
266: """download prepared set"""
267: filename=os.path.join(tdir,fn)
268:
269:
270: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s" """%"downloadFileFolder.tgz")
271: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
272: len=os.stat(filename)[6]
273: self.REQUEST.RESPONSE.setHeader("Content-Length",len)
274: images=file(filename).read()
275: self.REQUEST.RESPONSE.write(images)
276: self.REQUEST.RESPONSE.close()
277:
278:
279:
280: def helpDownload(self):
281: """download help"""
282:
283: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','helpDownload')).__of__(self)
284: return pt()
285:
286: def generateIndexHTML_image(self,RESPONSE=None):
287: """lege standard index.html an"""
288:
289:
290: if not self.ZopeFind(self,obj_ids=['index.html']):
291: zt=ZopePageTemplate('index.html')
292: self._setObject('index.html',zt)
293: default_content_fn = os.path.join(package_home(globals()),
294: 'zpt/versionFileFolderMain_image.zpt')
295: text = open(default_content_fn).read()
296: zt.pt_edit(text, 'text/html')
297:
298: else:
299: return "already exists!"
300:
301: if RESPONSE is not None:
302: RESPONSE.redirect('manage_main')
303:
304:
305: def generateAddFileForm(self,RESPONSE=None):
306: """lege standard addfileform an"""
307: #TODO: write generateaddfileform only a dummy at them moment
308:
309: if not self.ZopeFind(self,obj_ids=['addFileForm.dtml']):
310: zt=ZopePageTemplate('index.html')
311: self._setObject('index.html',zt)
312: default_content_fn = os.path.join(package_home(globals()),
313: 'zpt/versionFileFolderMain.zpt')
314: text = open(default_content_fn).read()
315: zt.pt_edit(text, 'text/html')
316:
317: else:
318: return "already exists!"
319:
320: if RESPONSE is not None:
321: RESPONSE.redirect('manage_main')
322:
323:
324: def generateIndexHTML(self,RESPONSE=None):
325: """lege standard index.html an"""
326:
327:
328: if not self.ZopeFind(self,obj_ids=['index.html']):
329: zt=ZopePageTemplate('index.html')
330: self._setObject('index.html',zt)
331: default_content_fn = os.path.join(package_home(globals()),
332: 'zpt/versionFileFolderMain.zpt')
333: text = open(default_content_fn).read()
334: zt.pt_edit(text, 'text/html')
335:
336: else:
337: return "already exists!"
338:
339: if RESPONSE is not None:
340: RESPONSE.redirect('manage_main')
341:
342:
343: def generateHistoryHTML(self,RESPONSE=None):
344: """lege standard index.html an"""
345:
346:
347:
348: if not self.ZopeFind(self,obj_ids=['history_template.html']):
349: zt=ZopePageTemplate('history_template.html')
350: self._setObject('history_template.html',zt)
351: default_content_fn = os.path.join(package_home(globals()),
352: 'zpt/versionHistory.zpt')
353: text = open(default_content_fn).read()
354: zt.pt_edit(text, 'text/html')
355:
356: else:
357: return "already exists!"
358:
359: if RESPONSE is not None:
360: RESPONSE.redirect('manage_main')
361:
362:
363:
364:
365: def getVersionedFiles(self,sortField='title'):
366: """get all versioned files"""
367:
368: def sortName(x,y):
369: return cmp(x[1].title.lower(),y[1].title.lower())
370:
371: def sortDate(x,y):
372: return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
373:
374:
375: def sortComment(x,y):
376:
377:
378:
379: try:
380: xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
381: except:
382: xc='ZZZZZZZZZZZZZ'.lower()
383: try:
384: yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
385: except:
386: yc='ZZZZZZZZZZZZZ'.lower()
387:
388:
389: if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
390:
391: try:
392: xc=x[1].getLastVersion().getVComment().lower()
393: except:
394: xc='ZZZZZZZZZZZZZ'.lower()
395:
396: if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
397: try:
398: yc=y[1].getLastVersion().getVComment().lower()
399: except:
400: yc='ZZZZZZZZZZZZZ'.lower()
401:
402:
403: return cmp(xc,yc)
404:
405: def sortAuthor(x,y):
406:
407: return cmp(x[1].getLastVersion().lastEditor().lower(),y[1].getLastVersion().lastEditor().lower())
408:
409: versionedFiles=self.ZopeFind(self,obj_metatypes=self.filesMetaType)
410:
411:
412: if sortField=='title':
413: versionedFiles.sort(sortName)
414: elif sortField=='date':
415: versionedFiles.sort(sortDate)
416: elif sortField=='author':
417: versionedFiles.sort(sortAuthor)
418: elif sortField=='comment':
419: versionedFiles.sort(sortComment)
420:
421: return versionedFiles
422:
423:
424: def header_html(self):
425: """zusätzlicher header"""
426: ext=self.ZopeFind(self,obj_ids=["header.html"])
427: if ext:
428: return ext[0][1]()
429: else:
430: return ""
431:
432:
433: security.declareProtected('View','index_html')
434: def index_html(self):
435: """main"""
436: ext=self.ZopeFind(self,obj_ids=["index.html"])
437: if ext:
438: return ext[0][1]()
439:
440: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionFileFolderMain')).__of__(self)
441: return pt()
442:
443:
444:
445: def addFileForm(self):
446: """add a file"""
447: ext=self.ZopeFind(self,obj_ids=["addFileForm.dtml"])
448: if ext:
449: return ext[0][1]('',globals(),version='1',AUTHENTICATED_USER=self.REQUEST.AUTHENTICATED_USER)
450:
451: out=DTMLFile('dtml/newFileAdd', globals(),Kind='VersionedFileObject',kind='versionedFileObject',version='1').__of__(self)
452: return out()
453:
454:
455: def addFile(self,vC,file,author,newName='',content_type='',RESPONSE=None):
456: """ add a new file"""
457: if newName=='':
458: filename=file.filename
459: id=filename[max(filename.rfind('/'),
460: filename.rfind('\\'),
461: filename.rfind(':'),
462: )+1:]
463:
464: else:
465: id=newName
466:
467: vC=self.REQUEST.form['vC']
468: manage_addVersionedFile(self,id,'','')
469: #if (getattr(self,'commentNonEmpty',0)==1) and vC.strip()=="":
470:
471:
472: ob=self._getOb(id)
473: ob.title=id
474: file2=file
475:
476: obj=ob.manage_addVersionedFileObject(id,vC,author,file2,content_type=content_type)
477: self.REQUEST.SESSION['objID']=ob.getId()
478: self.REQUEST.SESSION['objID_parent']=None
479:
480: if obj.getSize()==0:
481: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
482: return pt()
483:
484: RESPONSE.redirect(self.REQUEST['URL1'])
485:
486:
487: def deleteEmptyObject(self,submit,RESPONSE=None):
488: """deleteemptyobject"""
489: if submit=="delete it":
490: if self.REQUEST.SESSION['objID_parent']:
491: obj=getattr(self,self.REQUEST.SESSION['objID_parent'])
492:
493: else:
494: obj=self
495: obj.manage_delObjects([self.REQUEST.SESSION['objID']])
496:
497: RESPONSE.redirect(self.REQUEST['URL1'])
498:
499:
500: manage_addVersionedFileFolderForm=DTMLFile('dtml/folderAdd', globals())
501:
502:
503: def manage_addVersionedFileFolder(self, id, title='',
504: createPublic=0,
505: createUserF=0,
506: REQUEST=None):
507: """Add a new Folder object with id *id*.
508:
509: If the 'createPublic' and 'createUserF' parameters are set to any true
510: value, an 'index_html' and a 'UserFolder' objects are created respectively
511: in the new folder.
512: """
513: ob=versionedFileFolder()
514: ob.id=str(id)
515: ob.title=title
516: self._setObject(id, ob)
517: ob=self._getOb(id)
518:
519: checkPermission=getSecurityManager().checkPermission
520:
521: if createUserF:
522: if not checkPermission('Add User Folders', ob):
523: raise Unauthorized, (
524: 'You are not authorized to add User Folders.'
525: )
526: ob.manage_addUserFolder()
527:
528:
529: if REQUEST is not None:
530: return self.manage_main(self, REQUEST, update_menu=1)
531:
532:
533:
534: class versionedFileObject(File):
535: """File Object im Folder"""
536: security= ClassSecurityInfo()
537: meta_type = "versionedFileObject"
538:
539: manage_editForm =DTMLFile('dtml/fileEdit',globals(),
540: Kind='File',kind='file')
541: manage_editForm._setName('manage_editForm')
542:
543:
544:
545:
546: security.declarePublic('getTitle')
547:
548: def getTitle(self):
549: """get title"""
550: return self.title
551:
552: security.declarePublic('getVComment')
553: def getVComment(self):
554: """get the comment of this file"""
555: if not hasattr(self,'vComment') or (not self.vComment) or (self.vComment.lstrip()==""):
556: return "Add comment"
557:
558: else:
559: return self.vComment
560:
561: def manageVCommentForm(self):
562: """add a comment"""
563:
564: self.REQUEST.SESSION['refer']=self.REQUEST['HTTP_REFERER']
565:
566:
567:
568: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addVComment')).__of__(self)
569: return pt()
570:
571: def manageVComment(self,text,comment_author,submit,REQUEST=None):
572: """manage comments"""
573: if submit =='change':
574: if text=='':
575: self.vComment=None
576: else:
577: self.vComment=text
578: self.vComment_author=comment_author
579:
580: self.vComment_date=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
581:
582: if self.REQUEST.SESSION.has_key('refer'):
583:
584: return REQUEST.RESPONSE.redirect(self.REQUEST.SESSION['refer'])
585: return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url()+"/history")
586:
587:
588: security.declarePublic('getVersionComment')
589: def getVersionComment(self):
590: """getversioncomment"""
591: return self.versionComment
592:
593: security.declarePublic('getTime')
594:
595: def getTime(self):
596: """getTime"""
597: #return self.bobobase_modification_time().ISO()
598: if hasattr(self,'time'):
599: return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
600: elif hasattr(self,'timefixed'):
601: return self.timefixed
602: else:
603: setattr(self,'timefixed',self.bobobase_modification_time().ISO())
604: return self.bobobase_modification_time().ISO()
605:
606:
607:
608:
609:
610: def download(self,REQUEST=None,RESPONSE=None):
611: """download and lock"""
612:
613: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getId())
614: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
615: #try:
616: # txt=self.index_html()
617: #except:
618: # txt=self.index_html(REQUEST,RESPONSE)
619: #
620: #self.REQUEST.RESPONSE.setHeader("Content-Length","str(len(txt)+1000)")
621:
622: self.content_type="application/octet-stream"
623: self.REQUEST.RESPONSE.redirect(self.absolute_url())
624: #txt=urllib.urlopen(self.absolute_url()).read()
625: #self.REQUEST.RESPONSE.write(txt)
626:
627:
628: #self.REQUEST.close()
629:
630: security.declareProtected('AUTHENTICATED_USER','downloadLocked')
631: def downloadLocked(self):
632: """download and lock"""
633:
634:
635: if repr(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
636: return "please login first"
637: if not self.aq_parent.lockedBy=="":
638: return "cannot be locked because is already locked by %s"%self.lockedBy
639: self.aq_parent.lockedBy=self.REQUEST['AUTHENTICATED_USER']
640:
641: self.content_type="application/octet-stream"
642: self.REQUEST.RESPONSE.redirect(self.absolute_url())
643:
644: def setVersionNumber(self,versionNumber):
645: """set version"""
646: self.versionNumber=versionNumber
647:
648:
649: security.declarePublic('getVersionNumber')
650:
651: def getVersionNumber(self):
652: """get version"""
653: return self.versionNumber
654:
655: security.declarePublic('getVersionComment')
656: def getVersionComment(self):
657: """get version"""
658: return self.versionComment
659:
660:
661:
662: security.declarePublic('lastEditor')
663:
664: def lastEditor(self):
665: """last Editor"""
666: if hasattr(self,'author'):
667: try:
668: ret=self.author.replace("-","\n")
669: except:#old version of versionded file sometimes stored the user object and not only the name the following corrects this
670: ret=str(self.author).replace("-","\n")
671: ret=ret.replace("\r","\n")
672: return ret.lstrip().rstrip()
673:
674: else:
675: jar=self._p_jar
676: oid=self._p_oid
677:
678: if jar is None or oid is None: return None
679:
680: return jar.db().history(oid)[0]['user_name']
681:
682:
683:
684:
685: manage_addVersionedFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='VersionedFileObject',kind='versionedFileObject', version='1')
686:
687: def manage_addVersionedFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='',
688: REQUEST=None):
689: """Add a new File object.
690:
691: Creates a new File object 'id' with the contents of 'file'"""
692:
693: id=str(id)
694: title=str(title)
695: content_type=str(content_type)
696: precondition=str(precondition)
697:
698: id, title = cookId(id, title, file)
699:
700: self=self.this()
701:
702: # First, we create the file without data:
703: self._setObject(id, versionedFileObject(id,title,'',content_type, precondition))
704: self._getOb(id).versionComment=str(vC)
705: self._getOb(id).time=time.localtime()
706:
707: setattr(self._getOb(id),'author',author)
708:
709: # Now we "upload" the data. By doing this in two steps, we
710: # can use a database trick to make the upload more efficient.
711: if file:
712: self._getOb(id).manage_upload(file)
713: if content_type:
714: self._getOb(id).content_type=content_type
715:
716: if REQUEST is not None:
717: REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
718:
719:
720:
721:
722: class versionedFile(CatalogAware,Folder):
723: """Versioniertes File"""
724:
725: default_catalog='fileCatalog'
726:
727: security= ClassSecurityInfo()
728:
729: security.declarePublic('getTitle')
730: def getTitle(self):
731: """get title"""
732: return self.title
733:
734: def PrincipiaSearchSource(self):
735: """Return cataloguable key for ourselves."""
736: return str(self)
737:
738: def __init__(self, id, title, lockedBy,author):
739: """init"""
740: self.id=id
741: self.title=title
742: self.lockedBy=lockedBy
743: self.author=author
744:
745: def manageImagesForm(self):
746: """manage Images attached to the file"""
747:
748: self.REQUEST.SESSION['refer']=self.REQUEST['HTTP_REFERER']
749:
750: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','manageImage')).__of__(self)
751: return pt()
752:
753: def manageImages(self,imageUrl=None,caption=None,REQUEST=None):
754: """manage URL"""
755: if imageUrl and (not imageUrl==""):
756: manage_AddImageZogiLib(self,libPath=imageUrl,caption=caption)
757:
758: if self.REQUEST.SESSION.has_key('refer'):
759:
760: return REQUEST.RESPONSE.redirect(self.REQUEST.SESSION['refer'])
761: return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url())
762:
763:
764:
765: def changeImages(self,caption=None,submit=None,id=None,REQUEST=None):
766: """manage URL"""
767: if submit=="change caption":
768: image=self.ZopeFind(self,obj_ids=[id])
769: if image:
770: image[0][1].caption=caption[0:]
771:
772: elif submit=="delete":
773: image=self.ZopeFind(self,obj_ids=[id])
774: if image:
775: self.manage_delObjects([image[0][1].getId()])
776:
777:
778: if self.REQUEST.SESSION.has_key('refer'):
779:
780: return REQUEST.RESPONSE.redirect(self.REQUEST.SESSION['refer'])
781: return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url())
782:
783:
784:
785:
786: def getImages(self):
787: """get Images"""
788: images=self.ZopeFind(self,obj_metatypes=["ImageZogiLib"])
789: if not images:
790: return None
791: else:
792: return images
793:
794: security.declarePublic('getComment')
795: def getComment(self):
796: """get the comment of this file"""
797: if not hasattr(self,'comment') or (not self.comment) or (self.comment.lstrip()==""):
798: return "Add comment"
799:
800: else:
801: return self.comment
802:
803:
804: meta_type="versionedFile"
805:
806: def manageCommentForm(self):
807: """add a comment"""
808: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addComment')).__of__(self)
809: return pt()
810:
811: def manageComment(self,text,comment_author,submit,REQUEST=None):
812: """manage comments"""
813: if submit =='change':
814: if text=='':
815: self.comment=None
816: else:
817: self.comment=text
818: self.comment_author=comment_author
819:
820: self.comment_date=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
821:
822: return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url())
823:
824: security.declarePublic('getLastChangeDate')
825:
826: def getLastChangeDate(self):
827: """get last change date"""
828: lv=self.getLastVersion()
829: time=lv.getTime()
830: return time
831:
832: def getLastEditor(self):
833: """get last change date"""
834: lv=self.getLastVersion()
835: le=lv.lastEditor()
836: return le
837:
838: def getLockedBy(self):
839: """get locked by"""
840: return str(self.lockedBy)
841:
842: security.declarePublic('getLastVersion')
843: def getLastVersion(self):
844: """Last Version"""
845: tmp=0
846: lastVersion=None
847:
848:
849: for version in self.ZopeFind(self):
850:
851: if hasattr(version[1],'versionNumber'):
852:
853: if int(version[1].versionNumber) > tmp:
854: tmp=int(version[1].versionNumber,)
855: lastVersion=version[1]
856: if lastVersion==None:
857: lastVersion=version[1]
858: lastVersion.versionNumber=1
859: return lastVersion
860:
861:
862: def diff(self,data):
863: """differenz between lastversion and data"""
864: d=Differ()
865: data=data.rstrip()
866: try:
867: tmp=self.getLastVersion().data.rstrip()
868: except:
869: tmp=str(self.getLastVersion().data).rstrip()
870: #print "XX",data,tmp
871:
872: try:
873: l=list(d.compare(data.splitlines(1),tmp.splitlines(1)))
874: except:
875: try:
876: l=list(d.compare(repr(data).splitlines(1),tmp.splitlines(1)))
877: except:
878: return 9999,[]
879:
880: plus=0
881: minus=0
882:
883: for a in l:
884: if a[0]=='+':
885: plus+=1
886: if a[0]=='-':
887: minus+=1
888:
889:
890: return max([plus,minus]),l
891: security.declarePublic('index_html')
892: def index_html(self):
893: """main view"""
894: lastVersion=self.getLastVersion()
895: #return "File:"+self.title+" Version:%i"%lastVersion.versionNumber," modified:",lastVersion.bobobase_modification_time()," size:",lastVersion.getSize(),"modified by:",lastVersion.lastEditor()
896: return "File: %s Version:%i modified:%s size:%s modified by:%s"%(self.title,lastVersion.versionNumber,lastVersion.getTime(),lastVersion.getSize(),lastVersion.lastEditor())
897:
898:
899:
900: security.declarePublic('getVersion')
901: def getVersion(self):
902: tmp=0
903: for version in self.ZopeFind(self):
904:
905: if hasattr(version[1],'versionNumber'):
906:
907: if int(version[1].versionNumber) > tmp:
908: tmp=int(version[1].versionNumber,)
909: return tmp+1
910:
911:
912: security.declareProtected('AUTHENTICATED_USER','unlock')
913:
914: def history(self):
915: """history"""
916:
917: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
918: if ext:
919: return getattr(self,ext[0][1].getId())()
920:
921: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self)
922: return pt()
923:
924: def getVersions(self):
925: """get all versions"""
926: ret=[]
927: for version in self.ZopeFind(self):
928: if hasattr(version[1],'versionNumber'):
929: ret.append((version[1].versionNumber,version[1]))
930: ret.sort(sortv)
931: return ret
932:
933: security.declareProtected('AUTHENTICATED_USER','forceunlock')
934: def forceunlock(self,RESPONSE=None):
935: """unlock"""
936: #safe who had the lock
937: if self.lockedBy:
938: self.brokenLock=str(self.lockedBy)
939: else:
940: self.brokenLock=""
941: self.lockedBy=''
942: return self.brokenLock
943:
944: security.declareProtected('AUTHENTICATED_USER','unlock')
945: def unlock(self,RESPONSE):
946: """unlock"""
947: if str(self.lockedBy) in [str(self.REQUEST['AUTHENTICATED_USER'])]:
948: self.lockedBy=''
949: RESPONSE.redirect(self.REQUEST['HTTP_REFERER'])
950: else:
951: return "Sorry, not locked by you! (%s,%s)"%(self.lockedBy,self.REQUEST['AUTHENTICATED_USER'])
952:
953:
954:
955: security.declareProtected('AUTHENTICATED_USER','addVersionedFileObjectForm')
956:
957: def addVersionedFileObjectForm(self):
958: """add a new version"""
959:
960: if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
961: return "please login first"
962: if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
963: ext=self.ZopeFind(self.aq_parent,obj_ids=["addNewVersion.dtml"])
964: if ext:
965: return ext[0][1]('',globals(),version=self.getVersion(),lastComment=self.getLastVersion().getVersionComment(),AUTHENTICATED_USER=self.REQUEST.AUTHENTICATED_USER)
966: else:
967: out=DTMLFile('dtml/fileAdd', globals(),Kind='VersionedFileObject',kind='versionedFileObject',version=self.getVersion()).__of__(self)
968: return out()
969: else:
970: return "Sorry file is locked by somebody else"
971:
972: def manage_addVersionedFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', RESPONSE=None):
973: """add"""
974: try: #der ganze vC unsinn muss ueberarbeitet werden
975: vC=self.REQUEST['vC']
976: except:
977: pass
978:
979: author=self.REQUEST['author']
980:
981: if changeName=="yes":
982: filename=file.filename
983: self.title=filename[max(filename.rfind('/'),
984: filename.rfind('\\'),
985: filename.rfind(':'),
986: )+1:]
987:
988:
989: if not newName=='':
990: self.title=newName[0:]
991:
992:
993:
994:
995:
996: positionVersionNum=getattr(self,'positionVersionNum','front')
997:
998: if positionVersionNum=='front':
999: id="V%i"%self.getVersion()+"_"+self.title
1000: else:
1001: tmp=os.path.splitext(self.title)
1002: if len(tmp)>1:
1003: id=tmp[0]+"_V%i"%self.getVersion()+tmp[1]
1004: else:
1005: id=tmp[0]+"_V%i"%self.getVersion()
1006:
1007:
1008: manage_addVersionedFileObject(self,id,vC,author,file,id,precondition, content_type)
1009: objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion()))
1010: self.REQUEST.SESSION['objID_parent']=self.getId()
1011:
1012: if getattr(self,'defaultFileCatalog',None):
1013:
1014: self.reindex_object()
1015:
1016: if RESPONSE:
1017: obj=self.ZopeFind(self,obj_ids=[id])[0][1]
1018: if obj.getSize()==0:
1019: self.REQUEST.SESSION['objID']=obj.getId()
1020: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
1021: return pt()
1022:
1023: else:
1024: RESPONSE.redirect(self.REQUEST['URL2'])
1025:
1026: else:
1027: return self.ZopeFind(self,obj_ids=[id])[0][1]
1028:
1029: security.declareProtected('AUTHENTICATED_USER','downloadLocked')
1030:
1031: def download(self):
1032: """download and lock"""
1033:
1034: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
1035: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1036:
1037: #try:
1038: # txt=self.getLastVersion.index_html()
1039: #except:
1040: # txt=self.getLastVersion.index_html(REQUEST,RESPONSE)
1041:
1042: #self.REQUEST.RESPONSE.setHeader("Content-Length","str(len(txt)+1000)")
1043:
1044: self.content_type="application/octet-stream"
1045: #self.REQUEST.RESPONSE.write("bl")
1046: #self.REQUEST.RESPONSE.write(txt)
1047: #self.REQUEST.close()
1048:
1049: #self.getLastVersion().content_type="application/octet-stream"
1050: self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getLastVersion().getId())
1051:
1052: security.declareProtected('AUTHENTICATED_USER','downloadLocked')
1053: def downloadLocked(self):
1054: """download and lock"""
1055:
1056: if repr(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
1057: return "please login first"
1058: if not self.lockedBy=="":
1059: return "cannot be locked because is already locked by %s"%self.lockedBy
1060: self.lockedBy=self.REQUEST['AUTHENTICATED_USER']
1061: self.getLastVersion().content_type="application/octet-stream"
1062: self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getLastVersion().getId())
1063:
1064: def manage_addVersionedFileForm(self):
1065: """interface for adding the OSAS_root"""
1066: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addVersionedFile.zpt')).__of__(self)
1067: return pt()
1068:
1069: def manage_addVersionedFile(self,id,title,lockedBy, author=None, RESPONSE=None):
1070: """add the OSAS_root"""
1071: newObj=versionedFile(id,title,lockedBy,author)
1072: self._setObject(id,newObj)
1073:
1074: if RESPONSE is not None:
1075: RESPONSE.redirect('manage_main')
1076:
1077:
1078: InitializeClass(versionedFile)
1079: InitializeClass(versionedFileFolder)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>