Attachment 'AttachTable.py'

Download

   1 """
   2     MoinMoin - AttachTable Macro
   3     Author: Erick Martin
   4 
   5     A macro to produce a table of attached pages, leveraged from the attach file action, and AttachList macro.
   6 
   7     Usage:
   8        [[AttachTable]]
   9        [[AttachTable(page=FrontPage,syntax=0)]]
  10        [[AttachTable(readonly=1,closed=1,syntax=1]]
  11 
  12     args:
  13        @page=string display the attachemnt table for a differnet page 
  14        @syntax=1 display the attachemt syntax in the table
  15        @closed=0 display the table in a closed/open state overrideing the defualt cfg value attach_table_compact
  16        @readonly=0 force the display the table in a readonly mode remove the delete option
  17 
  18     @copyright: 2006 Erick Martin
  19     @copyright: 2004 Jacob Cohen, Nigel Metheringham
  20     @license: GNU GPL, see COPYING for details.
  21 """
  22 
  23 import os, urllib, time
  24 from MoinMoin import config, wikiutil
  25 from MoinMoin.action.AttachFile import getAttachDir, getAttachUrl
  26 
  27 def _get_files(base_dir):
  28     if os.path.isdir(base_dir):
  29         files = map(lambda a: a.decode(config.charset), os.listdir(base_dir))
  30         files.sort()
  31         return files
  32     return []
  33 
  34 def _get_fileid( base_dir ):
  35 
  36     file_id = 1000
  37 
  38     if os.path.isdir( base_dir ) and os.name == 'posix':
  39         inode = os.stat(base_dir.encode(config.charset))[1]
  40         dev = os.stat(base_dir.encode(config.charset))[2]
  41         file_id = "%(dev)d%(inode)d" % { 'inode' : inode, 'dev' : dev }
  42     else:
  43         file_id = 0
  44         for i in range(len(base_dir)):
  45            file_id = file_id + ord(base_dir[i])
  46 
  47     return file_id
  48 
  49 def _table_row( d ):
  50     str = ( '   <tr style="display:">\n'
  51             '      <td>\n'
  52             '        %(data_1)s\n'
  53             '        <p>\n'
  54             '        %(data_2)s\n'
  55             '      </td>\n'
  56             '      <td> %(data_3)s </td>\n'
  57             '      <td> %(data_4)s </td>\n'
  58             '      <td> %(data_5)s </td>\n'
  59             '   </tr>\n' ) % d
  60     return str
  61 
  62 def file_table( request, base_dir, pagename, display_table_closed = 0, display_attach_syntax = 1, readonly = 0):
  63 
  64     _ = request.getText
  65 
  66     files = _get_files(base_dir)
  67 
  68     action = 'AttachFile'
  69 
  70     page_url = wikiutil.quoteWikinameURL(pagename)
  71 
  72     # wikiutil.link_tag does not support title so we do it long hand
  73     manage_url = '<a href="%(baseurl)s/%(page_url)s?action=%(action)s" title="%(title)s" >%(text)s</a>' % {
  74         'baseurl' : request.getScriptname(),
  75         'page_url' : page_url,
  76         'action' : action,
  77         'text' : _('Add/Manage'),
  78         'title' : _('Add/Manage uploaded files'),
  79     }
  80 
  81     if not files:
  82         return '<br>\n%(icon)s %(manage_url)s files for the <strong>%(pagename)s</strong> 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'
  93     table_open_file_name = 'table-close'
  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     java_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     str = ( "\n"
 123             '<script type="text/javascript">' "\n"
 124             "<!--\n"
 125             "%(java_function)s\n"
 126             "--> </script>\n"
 127             "\n" ) % { 'java_function' : java_function, }
 128 
 129 
 130     file_id = _get_fileid( base_dir )
 131 
 132     str = str + '\n<div class="attachmentTable" >\n'
 133 
 134     table_caption = ( '<a onClick="showHideContents(%(file_id)s);" title="Click to open/close">'
 135                   '<img id="a%(file_id)s" align="middle" border=0 src="%(open_image)s"'
 136                   'alt=""></a>\n'
 137                   ' %(manage_url)s to the %(num_files)s file(s) attached to the <strong>%(pagename)s</strong> page' ) % {
 138                      'file_id' :  file_id,
 139                      'open_image' : open_image,
 140                      'num_files' :  len(files),
 141                      'pagename' : pagename,
 142                      'manage_url' : manage_url, }
 143 
 144     str = str + ( '<br>\n'
 145                   '%(table_caption)s\n'
 146                   '<table id="t%(file_id)s" >\n'
 147                   '   <tr style="display:">\n'
 148                   '     <th>Name<p>Wiki Include Syntax</th>\n'
 149                   '     <th>Size</th>\n'
 150                   '     <th>Date</th>\n'
 151                   '     <th>Action</th>\n'
 152                   '   </tr>\n') % {
 153                      'file_id' :  file_id,
 154                      'table_caption' :  table_caption, }
 155 
 156     # the user cant delete so force readonly mode
 157     if not request.user.may.delete(pagename):
 158         readonly = 1
 159 
 160     for file in files:
 161         fsize = float(os.stat(os.path.join(base_dir,file).encode(config.charset))[6]) # in byte
 162         mtime = os.stat(os.path.join(base_dir,file).encode(config.charset))[8]
 163         fsize = "%.1f" % (fsize / 1024)
 164         fdate = time.ctime(mtime)
 165         urlfile = urllib.quote_plus(file.encode(config.charset))
 166 
 167         base, ext = os.path.splitext(file)
 168         get_url = getAttachUrl(pagename, file, request, escaped=1)
 169         parmdict = { 'page_url': page_url, 'action': action,
 170                     'urlfile': urlfile, 'label_del': label_del,
 171                     'base': base, 'label_edit': label_edit,
 172                     'label_view': label_view,
 173                     'get_url': get_url, 'label_get': label_get,
 174                     'file': file, 'fsize': fsize,
 175                     'pagename': pagename}
 176 
 177         del_link = ''
 178         if not readonly:
 179             action_args = 'do=del&amp;target=%(urlfile)s' % { 
 180                'urlfile' : urlfile,
 181             }
 182             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 183                'page_url' : page_url,
 184                'action' : action,
 185                'action_args' : action_args,
 186             }
 187             del_link = wikiutil.link_tag(request, url, text=label_del,
 188                                          formatter=request.formatter)
 189 
 190 
 191         if ext == '.draw':
 192             action_args = 'drawing=%(base)s' % { 
 193                'base' : base,
 194             }
 195             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 196                'page_url' : page_url,
 197                'action' : action,
 198                'action_args' : action_args,
 199             }
 200             viewlink = wikiutil.link_tag(request, url, text=label_edit,
 201                                          formatter=request.formatter)
 202         else:
 203             action_args = 'do=view&amp;target=%(urlfile)s' % { 
 204                'urlfile' : urlfile,
 205             }
 206             url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 207                'page_url' : page_url,
 208                'action' : action,
 209                'action_args' : action_args,
 210             }
 211             viewlink = wikiutil.link_tag(request, url, text=label_view,
 212                                          formatter=request.formatter)
 213 
 214 
 215         image = ""
 216         if ext in request.theme.icons:
 217             image = request.theme.make_icon( ext )
 218         else:
 219             image = request.theme.make_icon( 'unknown' )
 220 
 221 
 222         parmdict['image'] = image
 223         parmdict['viewlink'] = viewlink
 224         parmdict['del_link'] = del_link
 225 
 226         parmdict['open_image'] = open_image
 227         
 228         action_args = 'do=get&amp;target=%(urlfile)s' % { 
 229            'urlfile' : urlfile,
 230         }
 231         url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
 232            'page_url' : page_url,
 233            'action' : action,
 234            'action_args' : action_args,
 235         }
 236         text = ' %(image)s %(file)s ' % { 'image' : image, 'file' : file }
 237         getlink = wikiutil.link_tag(request, url, text=text,
 238                                     formatter=request.formatter)
 239 
 240         parmdict['getlink'] = getlink
 241 
 242         depth = len(file.split(os.path.sep)) - 1
 243         indent_txt = "<div class=indent%d>\n         " % depth
 244 
 245         if not os.path.isdir(os.path.join(base_dir,file).encode(config.charset)):
 246             data_5 = ( '\n'
 247                       '         %(viewlink)s\n'
 248                       '         <a href="%(get_url)s"> %(label_get)s </a>\n'
 249                       '         %(del_link)s\n     ' ) % parmdict
 250             data_2 = '&nbsp;'
 251             if display_attach_syntax:
 252                 if pagename == request.formatter.page.page_name:
 253                     data_2 = 'attachment:%(file)s' % { 'file' : wikiutil.url_quote(file) }
 254                 else:
 255                     data_2 = 'attachment:%(pagename)s/%(file)s' % { 
 256                        'file' : wikiutil.url_quote(file),
 257                        'pagename' : pagename }
 258 
 259             str = str + _table_row( { 
 260                                       'data_1' : indent_txt + '<strong>%(getlink)s</strong>' % parmdict,
 261                                       'data_2' : data_2,
 262                                       'data_3' : '%(fsize)s&nbsp;KB' % parmdict,
 263                                       'data_4' : '%(fdate)s' % { 'fdate' : fdate },
 264                                       'data_5' : data_5,
 265                                     } )
 266 
 267     str = str + '\n</table>\n</div>\n'
 268 
 269     if display_table_closed:
 270         close_str = ( '\n<script type="text/javascript">\n'
 271                       '<!--\nshowHideContents(%(file_id)s);\n-->\n'
 272                       '</script>\n' ) % { 'file_id' :  file_id, }
 273         str = str + close_str
 274 
 275 
 276     return str
 277 
 278 def getArgs(string, arguments):
 279     """
 280     @param string: string from the wiki markup [[NewPage(string)]]
 281     @rtype: dict
 282     @return: dictionary with macro options
 283     """
 284     if not string:
 285         return {}
 286     args = {}
 287     for s in string.split(','):
 288         if s and s.find('=') > 0:
 289             key, value = s.split('=', 1)
 290             if key and value:
 291                 args[str(key.strip())] = value.strip()
 292     return args
 293 
 294 
 295 def execute(macro, options):
 296     """
 297     """
 298 
 299     arguments = ['page', 'syntax', 'closed', 'readonly']
 300 
 301     args = getArgs( options, arguments )
 302 
 303     pagename = args.get('page', macro.formatter.page.page_name)
 304 
 305     default_attach_syntax = 1
 306     if not pagename == macro.formatter.page.page_name:
 307         default_attach_syntax = 0
 308 
 309     # access directory
 310     attach_dir = getAttachDir(macro.request, pagename)
 311 
 312     default_table_closed = 0
 313     if hasattr(macro.request.cfg, 'attach_table_compact'):
 314         default_table_closed = macro.request.cfg.attach_table_compact
 315 
 316     display_attach_syntax = int(args.get('syntax', default_attach_syntax))
 317     table_closed = int(args.get('closed', default_table_closed))
 318     table_readonly = int(args.get('readonly', 0))
 319 
 320     return file_table( macro.request, attach_dir, pagename,
 321                        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-09-21 16:44:10, 0.7 KB) [[attachment:AttachTable.css]]
  • [get | view] (2010-05-01 04:32:20, 11.3 KB) [[attachment:AttachTable.py]]
  • [get | view] (2006-09-21 16:42:19, 51.8 KB) [[attachment:example.png]]
  • [get | view] (2006-09-21 16:43:45, 0.2 KB) [[attachment:table-close.png]]
  • [get | view] (2006-09-21 16:43:23, 0.1 KB) [[attachment:table-null.png]]
  • [get | view] (2006-09-21 16:43:34, 0.2 KB) [[attachment:table-open.png]]
 All files | Selected Files: delete move to page copy to page

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