Attachment 'AttachTable.py'

Download

   1 """
   2     MoinMoin - AttachTable Macro
   3     
   4     A macro to produce a table of files attached to a page.
   5 
   6     Usage:
   7        [[AttachTable]]
   8        [[AttachTable(page=FrontPage, preview=1)]]
   9        [[AttachTable(readonly=1, closed=1, syntax=1]]
  10 
  11     args:
  12        @page=string display the attachemnt table for a different page
  13        @preview=1 if the attachment is a jpg/gif/png file, show a thumbnail image
  14        @syntax=1 display the wiki syntax how to reference to an attachment
  15        @closed=0 display the table in a closed/open state overriding the default cfg value 'attach_table_compact'
  16        @readonly=0 force the display the table in a readonly mode, i.e. remove the 'delete attachment' option
  17 
  18     @copyright: 2007 Oliver Siemoneit
  19     @copyright: 2006 Erick Martin, Oliver Siemoneit
  20     @copyright: 2004 Jacob Cohen, Nigel Metheringham
  21     @license: GNU GPL, see COPYING for details.
  22 
  23 """
  24 
  25 import os, urllib, time, random
  26 from MoinMoin import config, wikiutil
  27 from MoinMoin.action.AttachFile import getAttachDir, getAttachUrl
  28 from MoinMoin.Page import Page
  29 
  30 def _get_files(base_dir):
  31     if os.path.isdir(base_dir):
  32         files = map(lambda a: a.decode(config.charset), os.listdir(base_dir))
  33         files.sort()
  34         return files
  35     return []
  36 
  37 def _table_row(d):
  38     row = ('   <tr style="display:">\n'
  39            '      <td>\n'
  40            '        %(data_1)s\n'
  41            '        <p>\n'
  42            '        %(data_2)s\n'
  43            '      </td>\n'
  44            '      <td> %(data_3)s </td>\n'
  45            '      <td> %(data_4)s </td>\n'
  46            '      <td> %(data_5)s </td>\n'
  47            '   </tr>\n') % d
  48     return row
  49 
  50 def make_thumbnail(request, formatter, attachment_url, ext):
  51     _ = request.getText
  52     kw = {}
  53     alt, icon, w, h = request.theme.icons[ext]
  54     kw['src'] = attachment_url
  55     kw['alt'] = _(alt)
  56     kw['height'] = h
  57     # display problems: Opera would also need width
  58     #kw['width'] = (h / orig_h) * orig_w
  59     return "%s" % formatter.image(**kw)
  60 
  61 def file_table(formatter, request, base_dir, pagename, preview_images=0, display_table_closed=0, display_attach_syntax=1, readonly=0):
  62     _ = request.getText
  63     attachments = _get_files(base_dir)
  64     action = 'AttachFile'
  65     page_url = wikiutil.quoteWikinameURL(pagename)
  66 
  67     # wikiutil.link_tag does not support title so we do it long hand
  68     manage_url = '<a href="%(baseurl)s/%(page_url)s?action=%(action)s" title="%(title)s" alt="%(title)s">%(text)s</a>' % {
  69         'baseurl': request.getScriptname(),
  70         'page_url': page_url,
  71         'action': action,
  72         'text': _('Add/Manage'),
  73         'title': _('Add/Manage uploaded files'), }
  74 
  75     if not attachments and Page(request, pagename).exists() == False:
  76         return _(u"\n%(icon)s %(manage_url)s files for the '''%(pagename)s''' page ''[No such page]''\n") % {
  77                    'icon': request.theme.make_icon('table-null'),
  78                    'pagename': pagename,
  79                    'manage_url': manage_url, }
  80 
  81     if not attachments:
  82         return _(u"\n%(icon)s %(manage_url)s files for the '''%(pagename)s''' page\n") % {
  83                    'icon': request.theme.make_icon('table-null'),
  84                    'pagename': pagename,
  85                    'manage_url': manage_url, }
  86 
  87     label_del = _("delete")
  88     label_get = _("download")
  89     label_edit = _("edit")
  90     label_view = _("view")
  91 
  92     table_closed_file_name = 'table-open.png'
  93     table_open_file_name = 'table-close.png'
  94 
  95     open_image = request.theme.img_url(table_open_file_name)
  96     closed_image = request.theme.img_url(table_closed_file_name)
  97 
  98     javascript_function = """
  99 // Toggle display of a folder's contents.
 100 function showHideContents ( idnum ) {
 101    the_table = document.getElementById( 't' + idnum );
 102 
 103    arrowObj  = document.getElementById( 'a' + idnum );
 104    // we use the image to determine if the table is open or closed
 105    if (arrowObj.src.indexOf('%(table_open_file_name)s') > -1) {
 106       arrowObj.src = '%(closed_image)s';
 107       display      = 'none';
 108    } else {
 109       arrowObj.src = '%(open_image)s';
 110       display      = '';
 111    }
 112 
 113    // change the open/closed state of the rows for the table
 114    for (var i = 0; i < the_table.rows.length; i++) {
 115       the_table.rows[i].style.display = display;
 116    }
 117 }
 118 """ % {'closed_image': closed_image,
 119        'open_image': open_image,
 120        'table_open_file_name': table_open_file_name, }
 121 
 122     html = ("\n"
 123             '<script type="text/javascript">' "\n"
 124             "<!--\n"
 125             "%(javascript_function)s\n"
 126             "--> </script>\n"
 127             "\n" ) % {'javascript_function': javascript_function, }
 128 
 129 
 130     file_id = random.randint(1, 99999999999)
 131 
 132     html = html + '\n<div class="attachmentTable" >\n'
 133 
 134     table_caption1 = ('<a onClick="showHideContents(%(file_id)s);" title="%(alt_title)s">'
 135                       '<img id="a%(file_id)s" align="middle" border=0 src="%(open_image)s"'
 136                       'alt="%(alt_title)s"></a>\n') % {
 137                       'file_id':  file_id,
 138                       'alt_title': _("Click to open/close table"),
 139                       'open_image': open_image, }
 140     
 141     table_caption2 = _(u"%(manage_url)s files for the '''%(pagename)s''' page ''[%(num_files)s file(s)]''") % {
 142                      'num_files':  len(attachments),
 143                      'pagename': pagename,
 144                      'manage_url': manage_url, }
 145 
 146     table_caption = table_caption1 + table_caption2
 147 
 148     if display_attach_syntax:
 149         html = html + ('<br>\n'
 150                        '%(table_caption)s\n'
 151                        '<table id="t%(file_id)s" >\n'
 152                        '   <tr style="display:">\n'
 153                        '     <th>%(name)s<p>%(syntax)s</th>\n'
 154                        '     <th>%(size)s</th>\n'
 155                        '     <th>%(date)s</th>\n'
 156                        '     <th>%(action)s</th>\n'
 157                        '   </tr>\n') % {
 158                           'file_id': file_id,
 159                           'table_caption': table_caption,
 160                           'name': _('Name'),
 161                           'syntax': _('Wiki Include Syntax'),
 162                           'size': _('Size'),
 163                           'date': _('Date'),
 164                           'action': _('Action'),}
 165     else:
 166         html = html + ('<br>\n'
 167                        '%(table_caption)s\n'
 168                        '<table id="t%(file_id)s" >\n'
 169                        '   <tr style="display:">\n'
 170                        '     <th>%(name)s</th>\n'
 171                        '     <th>%(size)s</th>\n'
 172                        '     <th>%(date)s</th>\n'
 173                        '     <th>%(action)s</th>\n'
 174                        '   </tr>\n') % {
 175                           'file_id':  file_id,
 176                           'table_caption':  table_caption,
 177                           'name': _('Name'),
 178                           'size': _('Size'),
 179                           'date': _('Date'),
 180                           'action': _('Action'),}
 181 
 182     # if user can't delete, force readonly mode
 183     if not request.user.may.delete(pagename):
 184         readonly = 1
 185 
 186     for attachment in attachments:
 187         fsize = float(os.stat(os.path.join(base_dir, attachment).encode(config.charset))[6]) # in byte
 188         mtime = os.stat(os.path.join(base_dir, attachment).encode(config.charset))[8]
 189         fsize = "%.1f" % (fsize/1024)
 190         fdate = time.ctime(mtime)
 191         urlfile = urllib.quote_plus(attachment.encode(config.charset))
 192 
 193         # build translation for datetime object
 194         _fdate = fdate.split(' ')
 195         _fdate[0] = _(_fdate[0])
 196         _fdate[1] = _(_fdate[1])
 197         fdate = _("%(day)s %(month)s %(date)s %(time)s %(year)s") % { 'day': _fdate[0],
 198                                                                       'month': _fdate[1],
 199                                                                       'date': _fdate[2],
 200                                                                       'time': _fdate[3],
 201                                                                       'year': _fdate[4], }
 202 
 203         base, ext = os.path.splitext(attachment)
 204         get_url = getAttachUrl(pagename, attachment, request, escaped=1)
 205         parmdict = {'page_url': page_url, 'action': action,
 206                     'urlfile': urlfile, 'label_del': label_del,
 207                     'base': base, 'label_edit': label_edit,
 208                     'label_view': label_view,
 209                     'get_url': get_url, 'label_get': label_get,
 210                     'file': attachment, 'fsize': fsize,
 211                     'pagename': pagename, }
 212 
 213         del_link = ''
 214         if not readonly:
 215             action_args = 'do=del&amp;target=%(urlfile)s' % {'urlfile' : urlfile, }
 216             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 217                'page_url': page_url,
 218                'action': action,
 219                'action_args': action_args, }
 220             del_link = wikiutil.link_tag(request, url, text=label_del,
 221                                          formatter=request.formatter)
 222 
 223 
 224         if ext == '.draw':
 225             action_args = 'drawing=%(base)s' % {'base': base, }
 226             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 227                'page_url': page_url,
 228                'action': action,
 229                'action_args': action_args, }
 230             
 231             viewlink = wikiutil.link_tag(request, url, text=label_edit,
 232                                          formatter=request.formatter)
 233         else:
 234             action_args = 'do=view&amp;target=%(urlfile)s' % {'urlfile': urlfile, }
 235             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 236                'page_url': page_url,
 237                'action': action,
 238                'action_args': action_args, }
 239             viewlink = wikiutil.link_tag(request, url, text=label_view,
 240                                          formatter=request.formatter)
 241 
 242         #build file or preview icon
 243         ext = ext.lower()
 244         do_preview = False
 245         #check if we have an icon for the extension
 246         if ext in request.theme.icons:
 247             if not preview_images:
 248                 ext = ext
 249             else:
 250                 if ext in ['.jpg', '.jpeg', '.jpe', '.gif', '.png']:
 251                     do_preview = True
 252         # if not: check whether ext belongs to a generic mimetype class
 253         elif ext in ['.py', '.js', '.jar', '.diff', '.patch']:
 254             ext = 'generic-text-x-source'
 255         elif ext in ['.tar', '.zip', '.bz2', '.rar', '.gz', '.cab', '.lha', '.arj']:
 256             ext = 'generic-x-archive'
 257         elif ext in ['.wav', '.aif', '.aifc', '.aiff', '.midi', '.mid', '.au']:
 258             ext = 'generic-x-audio'
 259         elif ext in ['.jpg', '.jpeg', '.jpe', '.gif', '.png']:
 260             ext = 'generic-x-image'
 261             if preview_images:
 262                 do_preview = True
 263         elif ext in ['.bmp', '.ps', '.eps', '.cdr', '.pct', '.mac', '.drw', '.svg']:
 264             ext = 'generic-x-image'
 265         elif ext in ['.mpeg', '.mpg', '.wmv', '.avi', '.mov', '.movie', '.qt']:
 266             ext = 'generic-x-video'
 267         elif ext in ['.htm', '.html']:
 268             ext = '.html'
 269         # if not: take icon 'unknown filetype'
 270         else:
 271             ext = 'unknown'
 272 
 273         # check if we have to do an image preview or not
 274         if preview_images and do_preview:
 275             image = make_thumbnail(request, formatter, get_url, ext)
 276         else:
 277             image = request.theme.make_icon(ext)
 278 
 279         parmdict['image'] = image
 280         parmdict['viewlink'] = viewlink
 281         parmdict['del_link'] = del_link
 282 
 283         parmdict['open_image'] = open_image
 284         
 285         action_args = 'do=get&amp;target=%(urlfile)s' % {'urlfile': urlfile, }
 286         url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 287            'page_url': page_url,
 288            'action': action,
 289            'action_args': action_args, }
 290         text = ' %(image)s %(file)s ' % {'image': image, 'file': attachment, }
 291         getlink = wikiutil.link_tag(request, url, text=text,
 292                                     formatter=request.formatter)
 293 
 294         parmdict['getlink'] = getlink
 295 
 296         depth = len(attachment.split(os.path.sep)) - 1
 297         indent_txt = "<div class=indent%d>\n         " % depth
 298 
 299         if not os.path.isdir(os.path.join(base_dir, attachment).encode(config.charset)):
 300             data_5 = ('\n'
 301                       '         %(viewlink)s\n'
 302                       '         <a href="%(get_url)s"> %(label_get)s </a>\n'
 303                       '         %(del_link)s\n     ') % parmdict
 304             data_2 = '&nbsp;'
 305             if display_attach_syntax:
 306                 if pagename == request.formatter.page.page_name:
 307                     data_2 = 'attachment:%(file)s' % {'file' : wikiutil.url_quote(attachment), }
 308                 else:
 309                     data_2 = 'attachment:%(pagename)s/%(file)s' % { 
 310                        'file': wikiutil.url_quote(attachment),
 311                        'pagename': pagename, }
 312 
 313             html = html + _table_row( { 
 314                                       'data_1' : indent_txt + '<strong>%(getlink)s</strong>' % parmdict,
 315                                       'data_2' : data_2,
 316                                       'data_3' : '%(fsize)s&nbsp;KB' % parmdict,
 317                                       'data_4' : '%(fdate)s' % { 'fdate' : fdate },
 318                                       'data_5' : data_5,
 319                                     } )
 320 
 321     html = html + '\n</table>\n</div>\n'
 322 
 323     if display_table_closed:
 324         close_str = ('\n<script type="text/javascript">\n'
 325                      '<!--\nshowHideContents(%(file_id)s);\n-->\n'
 326                      '</script>\n' ) % { 'file_id' :  file_id, }
 327         html = html + close_str
 328 
 329 
 330     return html
 331 
 332 def getArgs(given_arguments, allowed_arguments):
 333     if not given_arguments:
 334         return {}
 335     args = {}
 336     for s in given_arguments.split(','):
 337         if s and s.find('=') > 0:
 338             key, value = s.split('=', 1)
 339             if key and value:
 340                 key = key.strip()
 341                 if key in allowed_arguments:
 342                     args[key] = value.strip()
 343     return args
 344 
 345 def execute(macro, options):
 346     arguments = ['page', 'preview', 'syntax', 'closed', 'readonly']
 347     args = getArgs(options, arguments)
 348     pagename = args.get('page', macro.formatter.page.page_name)
 349 
 350     # access directory
 351     attach_dir = getAttachDir(macro.request, pagename)
 352 
 353     default_table_closed = 0
 354     if hasattr(macro.request.cfg, 'attach_table_compact'):
 355         default_table_closed = macro.request.cfg.attach_table_compact
 356     table_closed = int(args.get('closed', default_table_closed))
 357 
 358     default_attach_syntax = 0
 359     display_attach_syntax = int(args.get('syntax', default_attach_syntax))
 360     
 361     table_readonly = int(args.get('readonly', 0))
 362     preview_images = int(args.get('preview', 0))
 363 
 364     return file_table(macro.formatter, macro.request, attach_dir, pagename,
 365                       preview_images, table_closed, display_attach_syntax, table_readonly)

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2006-12-29 15:02:33, 14.7 KB) [[attachment:AttachTable.py]]
  • [get | view] (2009-08-11 07:04:46, 53.6 KB) [[attachment:TaskPlanner-1.8.4.py]]
  • [get | view] (2010-01-23 14:17:02, 52.7 KB) [[attachment:TaskPlanner-1.9.1.py]]
  • [get | view] (2007-04-14 15:35:39, 49.1 KB) [[attachment:TaskPlanner.py]]
  • [get | view] (2007-02-01 07:00:31, 243.0 KB) [[attachment:TaskPlanner.zip]]
  • [get | view] (2009-08-11 07:05:54, 56.5 KB) [[attachment:TaskPlanner1.8.4plusEmail.py]]
  • [get | view] (2006-12-29 19:46:46, 146.4 KB) [[attachment:TaskPlannerAttachTableIcons.zip]]
  • [get | view] (2007-08-24 20:11:02, 244.6 KB) [[attachment:TaskPlanner_LlubNek.zip]]
  • [get | view] (2007-04-02 14:42:44, 15.3 KB) [[attachment:TaskTable.py]]
  • [get | view] (2006-12-29 19:45:58, 66.9 KB) [[attachment:__init__.py]]
  • [get | view] (2006-12-29 19:45:29, 5.0 KB) [[attachment:_init_.diff]]
  • [get | view] (2006-12-26 16:49:56, 63.8 KB) [[attachment:addtask.jpg]]
  • [get | view] (2007-01-01 22:27:54, 3.8 KB) [[attachment:classic_theme.jpg]]
  • [get | view] (2008-05-07 16:42:25, 201.5 KB) [[attachment:clickingerror.jpg]]
  • [get | view] (2006-12-26 16:55:30, 9.7 KB) [[attachment:common.css]]
  • [get | view] (2006-12-26 16:55:03, 1.1 KB) [[attachment:common.diff]]
  • [get | view] (2007-01-01 22:27:36, 13.8 KB) [[attachment:common_icons.jpg]]
  • [get | view] (2006-12-26 16:53:07, 3.1 KB) [[attachment:de.AttachTable.po]]
  • [get | view] (2006-12-26 16:52:44, 7.4 KB) [[attachment:de.TaskPlanner.po]]
  • [get | view] (2006-12-26 16:50:48, 72.5 KB) [[attachment:imagepreview.jpg]]
  • [get | view] (2006-12-26 16:50:21, 78.2 KB) [[attachment:tasktable.jpg]]
  • [get | view] (2008-05-07 16:42:29, 8.4 KB) [[attachment:traceback_taskplanner.html]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.