comparison MoinMoin/action/AttachFile.py @ 3150:8ae94675b9f9

AttachFile: some cosmetical source changes
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Thu, 28 Feb 2008 21:34:22 +0100
parents 6749e003d7e2
children 863d90c05507
comparison
equal deleted inserted replaced
3149:6749e003d7e2 3150:8ae94675b9f9
43 ############################################################################# 43 #############################################################################
44 44
45 class AttachmentAlreadyExists(Exception): 45 class AttachmentAlreadyExists(Exception):
46 pass 46 pass
47 47
48
48 def getBasePath(request): 49 def getBasePath(request):
49 """ Get base path where page dirs for attachments are stored. 50 """ Get base path where page dirs for attachments are stored. """
50 """
51 return request.rootpage.getPagePath('pages') 51 return request.rootpage.getPagePath('pages')
52 52
53 53
54 def getAttachDir(request, pagename, create=0): 54 def getAttachDir(request, pagename, create=0):
55 """ Get directory where attachments for page `pagename` are stored. 55 """ Get directory where attachments for page `pagename` are stored. """
56 """
57 if request.page and pagename == request.page.page_name: 56 if request.page and pagename == request.page.page_name:
58 page = request.page # reusing existing page obj is faster 57 page = request.page # reusing existing page obj is faster
59 else: 58 else:
60 page = Page(request, pagename) 59 page = Page(request, pagename)
61 return page.getPagePath("attachments", check_create=create) 60 return page.getPagePath("attachments", check_create=create)
61
62 62
63 def absoluteName(url, pagename): 63 def absoluteName(url, pagename):
64 """ Get (pagename, filename) of an attachment: link 64 """ Get (pagename, filename) of an attachment: link
65 @param url: PageName/filename.ext or filename.ext (unicode) 65 @param url: PageName/filename.ext or filename.ext (unicode)
66 @param pagename: name of the currently processed page (unicode) 66 @param pagename: name of the currently processed page (unicode)
72 if len(pieces) == 1: 72 if len(pieces) == 1:
73 return pagename, pieces[0] 73 return pagename, pieces[0]
74 else: 74 else:
75 return u"/".join(pieces[:-1]), pieces[-1] 75 return u"/".join(pieces[:-1]), pieces[-1]
76 76
77
77 def attachUrl(request, pagename, filename=None, **kw): 78 def attachUrl(request, pagename, filename=None, **kw):
78 # filename is not used yet, but should be used later to make a sub-item url 79 # filename is not used yet, but should be used later to make a sub-item url
79 if kw: 80 if kw:
80 qs = '?%s' % wikiutil.makeQueryString(kw, want_unicode=False) 81 qs = '?%s' % wikiutil.makeQueryString(kw, want_unicode=False)
81 else: 82 else:
82 qs = '' 83 qs = ''
83 return "%s/%s%s" % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename), qs) 84 return "%s/%s%s" % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename), qs)
85
84 86
85 def getAttachUrl(pagename, filename, request, addts=0, escaped=0, do='get', drawing='', upload=False): 87 def getAttachUrl(pagename, filename, request, addts=0, escaped=0, do='get', drawing='', upload=False):
86 """ Get URL that points to attachment `filename` of page `pagename`. """ 88 """ Get URL that points to attachment `filename` of page `pagename`. """
87 if upload: 89 if upload:
88 if not drawing: 90 if not drawing:
135 """ 137 """
136 if isinstance(filename, unicode): 138 if isinstance(filename, unicode):
137 filename = filename.encode(config.charset) 139 filename = filename.encode(config.charset)
138 return os.path.join(getAttachDir(request, pagename, create=1), filename) 140 return os.path.join(getAttachDir(request, pagename, create=1), filename)
139 141
142
140 def exists(request, pagename, filename): 143 def exists(request, pagename, filename):
141 """ check if page <pagename> has a file <filename> attached """ 144 """ check if page <pagename> has a file <filename> attached """
142 fpath = getFilename(request, pagename, filename) 145 fpath = getFilename(request, pagename, filename)
143 return os.path.exists(fpath) 146 return os.path.exists(fpath)
144 147
148
145 def size(request, pagename, filename): 149 def size(request, pagename, filename):
146 """ return file size of file attachment """ 150 """ return file size of file attachment """
147 fpath = getFilename(request, pagename, filename) 151 fpath = getFilename(request, pagename, filename)
148 return os.path.getsize(fpath) 152 return os.path.getsize(fpath)
149 153
154
150 def info(pagename, request): 155 def info(pagename, request):
151 """ Generate snippet with info on the attachment for page `pagename`. 156 """ Generate snippet with info on the attachment for page `pagename`. """
152 """
153 _ = request.getText 157 _ = request.getText
154 158
155 attach_dir = getAttachDir(request, pagename) 159 attach_dir = getAttachDir(request, pagename)
156 files = [] 160 files = []
157 if os.path.isdir(attach_dir): 161 if os.path.isdir(attach_dir):
162 'count': len(files), 166 'count': len(files),
163 'link': wikiutil.escape(link) 167 'link': wikiutil.escape(link)
164 } 168 }
165 return "\n<p>\n%s\n</p>\n" % attach_info 169 return "\n<p>\n%s\n</p>\n" % attach_info
166 170
171
167 def add_attachment(request, pagename, target, filecontent, overwrite=0): 172 def add_attachment(request, pagename, target, filecontent, overwrite=0):
173 _ = request.getText
174
168 # replace illegal chars 175 # replace illegal chars
169
170 _ = request.getText
171
172 target = wikiutil.taintfilename(target) 176 target = wikiutil.taintfilename(target)
173 177
174 # set mimetype from extension, or from given mimetype 178 # set mimetype from extension, or from given mimetype
175 #type, encoding = wikiutil.guess_type(target) 179 #type, encoding = wikiutil.guess_type(target)
176 #if not type: 180 #if not type:
366 def _get_files(request, pagename): 370 def _get_files(request, pagename):
367 attach_dir = getAttachDir(request, pagename) 371 attach_dir = getAttachDir(request, pagename)
368 if os.path.isdir(attach_dir): 372 if os.path.isdir(attach_dir):
369 files = [fn.decode(config.charset) for fn in os.listdir(attach_dir)] 373 files = [fn.decode(config.charset) for fn in os.listdir(attach_dir)]
370 files.sort() 374 files.sort()
371 return files 375 else:
372 return [] 376 files = []
377 return files
373 378
374 379
375 def _get_filelist(request, pagename): 380 def _get_filelist(request, pagename):
376 return _build_filelist(request, pagename, 1, 0) 381 return _build_filelist(request, pagename, 1, 0)
382
377 383
378 def _subdir_exception(zf): 384 def _subdir_exception(zf):
379 """ 385 """
380 Checks for the existance of one common subdirectory shared among 386 Checks for the existance of one common subdirectory shared among
381 all files in the zip file. If this is the case, returns a dict of 387 all files in the zip file. If this is the case, returns a dict of
383 as the user would expect. 389 as the user would expect.
384 """ 390 """
385 391
386 b = zf.namelist() 392 b = zf.namelist()
387 if not '/' in b[0]: 393 if not '/' in b[0]:
388 return False #No directory 394 return False # no directory
389 slashoffset = b[0].index('/') 395 slashoffset = b[0].index('/')
390 directory = b[0][:slashoffset] 396 directory = b[0][:slashoffset]
391 for origname in b: 397 for origname in b:
392 if origname.rfind('/') != slashoffset or origname[:slashoffset] != directory: 398 if origname.rfind('/') != slashoffset or origname[:slashoffset] != directory:
393 return False #Multiple directories or different directory 399 return False # multiple directories or different directory
394 names = {} 400 names = {}
395 for origname in b: 401 for origname in b:
396 names[origname] = origname[slashoffset+1:] 402 names[origname] = origname[slashoffset+1:]
397 return names #Returns dict of {origname: safename} 403 return names # returns dict of {origname: safename}
404
398 405
399 def error_msg(pagename, request, msg): 406 def error_msg(pagename, request, msg):
400 request.theme.add_msg(msg, "error") 407 request.theme.add_msg(msg, "error")
401 Page(request, pagename).send_page() 408 Page(request, pagename).send_page()
402 409
500 'overwrite_checked': ('', 'checked')[request.form.get('overwrite', ['0'])[0] == '1'], 507 'overwrite_checked': ('', 'checked')[request.form.get('overwrite', ['0'])[0] == '1'],
501 'upload_button': _('Upload'), 508 'upload_button': _('Upload'),
502 'textcha': TextCha(request).render(), 509 'textcha': TextCha(request).render(),
503 }) 510 })
504 511
505 #<dt>%(upload_label_mime)s</dt>
506 #<dd><input type="text" name="mime" size="50"></dd>
507 # 'upload_label_mime': _('MIME Type (optional)'),
508
509 request.write('<h2>' + _("Attached Files") + '</h2>') 512 request.write('<h2>' + _("Attached Files") + '</h2>')
510 request.write(_get_filelist(request, pagename)) 513 request.write(_get_filelist(request, pagename))
511 514
512 if not writeable: 515 if not writeable:
513 request.write('<p>%s</p>' % _('You are not allowed to attach a file to this page.')) 516 request.write('<p>%s</p>' % _('You are not allowed to attach a file to this page.'))
519 ############################################################################# 522 #############################################################################
520 ### Web interface for file upload, viewing and deletion 523 ### Web interface for file upload, viewing and deletion
521 ############################################################################# 524 #############################################################################
522 525
523 def execute(pagename, request): 526 def execute(pagename, request):
524 """ Main dispatcher for the 'AttachFile' action. 527 """ Main dispatcher for the 'AttachFile' action. """
525 """
526 _ = request.getText 528 _ = request.getText
527 529
528 if action_name in request.cfg.actions_excluded: 530 if action_name in request.cfg.actions_excluded:
529 msg = _('File attachments are not allowed in this wiki!') 531 msg = _('File attachments are not allowed in this wiki!')
530 error_msg(pagename, request, msg) 532 error_msg(pagename, request, msg)
617 msg = _('Unsupported AttachFile sub-action: %s') % (wikiutil.escape(do), ) 619 msg = _('Unsupported AttachFile sub-action: %s') % (wikiutil.escape(do), )
618 620
619 if msg: 621 if msg:
620 error_msg(pagename, request, msg) 622 error_msg(pagename, request, msg)
621 623
624
622 def upload_form(pagename, request, msg=''): 625 def upload_form(pagename, request, msg=''):
623 _ = request.getText 626 _ = request.getText
624 627
625 request.emit_http_headers() 628 request.emit_http_headers()
626 # Use user interface language for this generated page 629 # Use user interface language for this generated page
631 send_uploadform(pagename, request) 634 send_uploadform(pagename, request)
632 request.write('</div>\n') # end content div 635 request.write('</div>\n') # end content div
633 request.theme.send_footer(pagename) 636 request.theme.send_footer(pagename)
634 request.theme.send_closing_html() 637 request.theme.send_closing_html()
635 638
639
636 def do_upload(pagename, request, overwrite): 640 def do_upload(pagename, request, overwrite):
637 _ = request.getText 641 _ = request.getText
638 642
639 # make filename 643 # make filename
640 filename = None 644 filename = None
714 718
715 # touch attachment directory to invalidate cache if new map is saved 719 # touch attachment directory to invalidate cache if new map is saved
716 if ext == '.map': 720 if ext == '.map':
717 os.utime(getAttachDir(request, pagename), None) 721 os.utime(getAttachDir(request, pagename), None)
718 722
723
719 def del_file(pagename, request): 724 def del_file(pagename, request):
720 _ = request.getText 725 _ = request.getText
721 726
722 filename, fpath = _access_file(pagename, request) 727 filename, fpath = _access_file(pagename, request)
723 if not filename: 728 if not filename:
732 index = Index(request) 737 index = Index(request)
733 if index.exists: 738 if index.exists:
734 index.remove_item(pagename, filename) 739 index.remove_item(pagename, filename)
735 740
736 upload_form(pagename, request, msg=_("Attachment '%(filename)s' deleted.") % {'filename': filename}) 741 upload_form(pagename, request, msg=_("Attachment '%(filename)s' deleted.") % {'filename': filename})
742
737 743
738 def move_file(request, pagename, new_pagename, attachment, new_attachment): 744 def move_file(request, pagename, new_pagename, attachment, new_attachment):
739 _ = request.getText 745 _ = request.getText
740 746
741 newpage = Page(request, new_pagename) 747 newpage = Page(request, new_pagename)
762 upload_form(pagename, request, msg=_("Nothing changed")) 768 upload_form(pagename, request, msg=_("Nothing changed"))
763 else: 769 else:
764 upload_form(pagename, request, msg=_("Page %(newpagename)s does not exists or you don't have enough rights.") % { 770 upload_form(pagename, request, msg=_("Page %(newpagename)s does not exists or you don't have enough rights.") % {
765 'newpagename': new_pagename}) 771 'newpagename': new_pagename})
766 772
773
767 def attachment_move(pagename, request): 774 def attachment_move(pagename, request):
768 _ = request.getText 775 _ = request.getText
769 if 'newpagename' in request.form: 776 if 'newpagename' in request.form:
770 new_pagename = request.form.get('newpagename')[0] 777 new_pagename = request.form.get('newpagename')[0]
771 else: 778 else:
779 else: 786 else:
780 upload_form(pagename, request, msg=_("Move aborted because empty attachment name")) 787 upload_form(pagename, request, msg=_("Move aborted because empty attachment name"))
781 788
782 attachment = request.form.get('oldattachmentname')[0] 789 attachment = request.form.get('oldattachmentname')[0]
783 move_file(request, pagename, new_pagename, attachment, new_attachment) 790 move_file(request, pagename, new_pagename, attachment, new_attachment)
791
784 792
785 def send_moveform(pagename, request): 793 def send_moveform(pagename, request):
786 _ = request.getText 794 _ = request.getText
787 795
788 filename, fpath = _access_file(pagename, request) 796 filename, fpath = _access_file(pagename, request)
832 </form>''' % d 840 </form>''' % d
833 thispage = Page(request, pagename) 841 thispage = Page(request, pagename)
834 request.theme.add_msg(formhtml, "dialog") 842 request.theme.add_msg(formhtml, "dialog")
835 return thispage.send_page() 843 return thispage.send_page()
836 844
845
837 def get_file(pagename, request): 846 def get_file(pagename, request):
838 import shutil 847 import shutil
839 848
840 filename, fpath = _access_file(pagename, request) 849 filename, fpath = _access_file(pagename, request)
841 if not filename: 850 if not filename:
867 ]) 876 ])
868 877
869 # send data 878 # send data
870 shutil.copyfileobj(open(fpath, 'rb'), request, 8192) 879 shutil.copyfileobj(open(fpath, 'rb'), request, 8192)
871 880
881
872 def install_package(pagename, request): 882 def install_package(pagename, request):
873 _ = request.getText 883 _ = request.getText
874 884
875 target, targetpath = _access_file(pagename, request) 885 target, targetpath = _access_file(pagename, request)
876 if not target: 886 if not target:
887 msg += "<br><pre>%s</pre>" % wikiutil.escape(package.msg) 897 msg += "<br><pre>%s</pre>" % wikiutil.escape(package.msg)
888 else: 898 else:
889 msg = _('The file %s is not a MoinMoin package file.') % wikiutil.escape(target) 899 msg = _('The file %s is not a MoinMoin package file.') % wikiutil.escape(target)
890 900
891 upload_form(pagename, request, msg=msg) 901 upload_form(pagename, request, msg=msg)
902
892 903
893 def unzip_file(pagename, request): 904 def unzip_file(pagename, request):
894 _ = request.getText 905 _ = request.getText
895 valid_pathname = lambda name: ('/' not in name) and ('\\' not in name) 906 valid_pathname = lambda name: ('/' not in name) and ('\\' not in name)
896 907
918 if zipfile.is_zipfile(fpath): 929 if zipfile.is_zipfile(fpath):
919 zf = zipfile.ZipFile(fpath) 930 zf = zipfile.ZipFile(fpath)
920 sum_size_over_all_valid_files = 0.0 931 sum_size_over_all_valid_files = 0.0
921 count_valid_files = 0 932 count_valid_files = 0
922 namelist = _subdir_exception(zf) 933 namelist = _subdir_exception(zf)
923 if not namelist: #if it's not handled by _subdir_exception() 934 if not namelist: # if it's not handled by _subdir_exception()
924 #Convert normal zf.namelist() to {origname:finalname} dict 935 # convert normal zf.namelist() to {origname:finalname} dict
925 namelist = {} 936 namelist = {}
926 for name in zf.namelist(): 937 for name in zf.namelist():
927 namelist[name] = name 938 namelist[name] = name
928 for (origname, finalname) in namelist.iteritems(): 939 for (origname, finalname) in namelist.iteritems():
929 if valid_pathname(finalname): 940 if valid_pathname(finalname):
971 else: 982 else:
972 msg = _('The file %(filename)s is not a .zip file.') % {'filename': filename} 983 msg = _('The file %(filename)s is not a .zip file.') % {'filename': filename}
973 984
974 upload_form(pagename, request, msg=wikiutil.escape(msg)) 985 upload_form(pagename, request, msg=wikiutil.escape(msg))
975 986
987
976 def send_viewfile(pagename, request): 988 def send_viewfile(pagename, request):
977 _ = request.getText 989 _ = request.getText
978 fmt = request.html_formatter 990 fmt = request.html_formatter
979 991
980 filename, fpath = _access_file(pagename, request) 992 filename, fpath = _access_file(pagename, request)
1006 colorizer.format(request.formatter) 1018 colorizer.format(request.formatter)
1007 return 1019 return
1008 except IOError: 1020 except IOError:
1009 pass 1021 pass
1010 1022
1011
1012 request.write(request.formatter.preformatted(1)) 1023 request.write(request.formatter.preformatted(1))
1013 # If we have text but no colorizing parser we try to decode file contents. 1024 # If we have text but no colorizing parser we try to decode file contents.
1014 content = open(fpath, 'r').read() 1025 content = open(fpath, 'r').read()
1015 content = wikiutil.decodeUnknownInput(content) 1026 content = wikiutil.decodeUnknownInput(content)
1016 content = wikiutil.escape(content) 1027 content = wikiutil.escape(content)
1081 ############################################################################# 1092 #############################################################################
1082 ### File attachment administration 1093 ### File attachment administration
1083 ############################################################################# 1094 #############################################################################
1084 1095
1085 def do_admin_browser(request): 1096 def do_admin_browser(request):
1086 """ Browser for SystemAdmin macro. 1097 """ Browser for SystemAdmin macro. """
1087 """
1088 from MoinMoin.util.dataset import TupleDataset, Column 1098 from MoinMoin.util.dataset import TupleDataset, Column
1089 _ = request.getText 1099 _ = request.getText
1090 1100
1091 data = TupleDataset() 1101 data = TupleDataset()
1092 data.columns = [ 1102 data.columns = [
1093 Column('page', label=('Page')), 1103 Column('page', label=('Page')),
1094 Column('file', label=('Filename')), 1104 Column('file', label=('Filename')),
1095 Column('size', label=_('Size'), align='right'), 1105 Column('size', label=_('Size'), align='right'),
1096 #Column('action', label=_('Action')),
1097 ] 1106 ]
1098 1107
1099 # iterate over pages that might have attachments 1108 # iterate over pages that might have attachments
1100 pages = request.rootpage.getPageList() 1109 pages = request.rootpage.getPageList()
1101 for pagename in pages: 1110 for pagename in pages:
1108 filepath = os.path.join(page_dir, filename) 1117 filepath = os.path.join(page_dir, filename)
1109 data.addRow(( 1118 data.addRow((
1110 Page(request, pagename).link_to(request, querystr="action=AttachFile"), 1119 Page(request, pagename).link_to(request, querystr="action=AttachFile"),
1111 wikiutil.escape(filename.decode(config.charset)), 1120 wikiutil.escape(filename.decode(config.charset)),
1112 os.path.getsize(filepath), 1121 os.path.getsize(filepath),
1113 # '',
1114 )) 1122 ))
1115 1123
1116 if data: 1124 if data:
1117 from MoinMoin.widget.browser import DataBrowserWidget 1125 from MoinMoin.widget.browser import DataBrowserWidget
1118 1126