Uploaded image for project: 'XWiki Platform'
  1. XWiki Platform
  2. XWIKI-14434

Add attachment filesize to XWiki.AllAttachments + allow to sort on column

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Duplicate
    • Affects Version/s: 3.5
    • Fix Version/s: None
    • Component/s: Distribution - Flavor
    • Labels:
      None
    • keywords:
      all attachments filesize attachment
    • Similar issues:

      Description

      I was looking for a way to display the filesizes in the XWiki.AllAttachments page, and find out large attachments that had been uploaded.

      The following is a modified 3.5 version of XWiki.AllAttachments and XWiki.AllAttachmentsResults, which implements this idea.
      (note I just overrode the display name of the column)

      XWiki.AllAttachments: (attached javascript object)

      (function(){
      
      if (typeof XWiki == "undefined") {
         XWiki = new Object();
      }
      
      if (typeof XWiki.index == "undefined") {
         XWiki.index = new Object();
      }
      
      var mimetypes = {
        "image/svg"                     : { "src" : "$xwiki.getSkinFile('icons/silk/vector.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.svg")}", "title" : "${msg.get("core.viewers.attachments.mime.svg")}" },
        "application/svg+xml"           : { "src" : "$xwiki.getSkinFile('icons/silk/vector.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.svg")}", "title" : "${msg.get("core.viewers.attachments.mime.svg")}" },
        "text/plain"                    : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_text.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.text")}", "title" : "${msg.get("core.viewers.attachments.mime.text")}"},
        "text/html"                     : { "src" : "$xwiki.getSkinFile('icons/silk/html.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.html")}", "title" : "${msg.get("core.viewers.attachments.mime.html")}"},
        "text/css"                      : { "src" : "$xwiki.getSkinFile('icons/silk/css.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.css")}", "title" : "${msg.get("core.viewers.attachments.mime.css")}" },
        "application/xml"               : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_code.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.xml")}", "title" : "${msg.get("core.viewers.attachments.mime.xml")}" },
        "application/pdf"               : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_acrobat.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.pdf")}", "title" : "${msg.get("core.viewers.attachments.mime.pdf")}" },
        "application/postscript"        : { "src" : "$xwiki.getSkinFile('icons/silk/page_red.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.ps")}",   "title" : "${msg.get("core.viewers.attachments.mime.ps")}"  },
        "application/msword"            : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_word.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.document")}", "title" : "${msg.get("core.viewers.attachments.mime.document")}"},
        "application/powerpoint"        : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_powerpoint.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.presentation")}", "title" : "${msg.get("core.viewers.attachments.mime.presentation")}" },
        "application/x-shockwave-flash" : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_flash.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.flash")}", "title" : "${msg.get("core.viewers.attachments.mime.flash")}" },
        "application/x-tar"             : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_compressed.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.tar")}", "title" : "${msg.get("core.viewers.attachments.mime.tar")}" },
        "application/zip"               : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_zip.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.zip")}", "title" : "${msg.get("core.viewers.attachments.mime.zip")}" },
        "application/x-gzip"            : { "src" : "$xwiki.getSkinFile('icons/silk/page_white_compressed.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.gz")}", "title" : "${msg.get("core.viewers.attachments.mime.gz")}"  },
        "application/java-archive"      : { "src" : "$xwiki.getSkinFile('icons/silk/cup.gif')", "alt" : "${msg.get("core.viewers.attachments.mime.jar")}", "title" : "${msg.get("core.viewers.attachments.mime.jar")}" }
      };
      
      /**
       * JavasScript equivalent of the #mimetype macro.
       * Returns a 20px * 20px image (as an element) corresponding to the passed mimetype.
       * First lookup if the type is in the mimetypes object above, then handles some other cases (starts/end with, etc.)
       * This function should be cleaned at the same time the mimetype images and macro are.
       */
      function getMimeTypeImage(type) {
        var image = undefined;
        if (mimetypes[type]) {
          image = new Element('img',{'src':mimetypes[type].src,'alt':mimetypes[type].alt,'title':mimetypes[type].title});
        }
        else if(type.match(/^image\//)) {
          image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/picture.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.image")}", 'title': "${msg.get("core.viewers.attachments.mime.image")}"});
        }
        else if(type.match(/^text\//)) {
          image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page_white_text.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.text")}", 'title': "${msg.get("core.viewers.attachments.mime.text")}"});
        }
        else if(type.match(/^audio\//)){
          image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/music.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.audio")}", 'title': "${msg.get("core.viewers.attachments.mime.audio")}"});
        }
        else if(type.match(/^video\//)){
          image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/film.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.video")}", 'title': "${msg.get("core.viewers.attachments.mime.video")}"});
        }
        else if(type=="application/octet-stream") {
          if (type.match(/\.xls$/)) {
            image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page_white_excel.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.spreadsheet")}", 'title': "${msg.get("core.viewers.attachments.mime.spreadsheet")}"});
          }
          else if (type.match(/\.bz$/)) {
            image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page_white_compressed.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.bz")}", 'title': "${msg.get("core.viewers.attachments.mime.bz")}"});
          }
          else if (type.match(/\.tgz$/)) {
            image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page_white_compressed.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.gz")}", 'title': "${msg.get("core.viewers.attachments.mime.gz")}"});
          }
          else if (type.match(/\.rar$/)) {
            image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page_white_compressed.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.rar")}", 'title': "${msg.get("core.viewers.attachments.mime.rar")}"});
          }
          else if (type.match(/\.(odt|odp|odf|ods|sxw|stw)$/)) {
            image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/page.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.office")}", 'title': "${msg.get("core.viewers.attachments.mime.office")}"});
          }
        } 
        else if (type.match(/^application\//)) {
          image = new Element('img', {'src':"$xwiki.getSkinFile('icons/silk/cog.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.exe")}", 'title': "${msg.get("core.viewers.attachments.mime.exe")}"});
        }
        if (typeof image == "undefined") {
          image = new Element('img', {'src': "$xwiki.getSkinFile('icons/silk/page_white.gif')", 'alt':"${msg.get("core.viewers.attachments.mime.attachment")}", 'title': "${msg.get("core.viewers.attachments.mime.attachment")}"});
        }
        image.style.width = '16px';
        image.style.height = '16px';
        return image;
      }
      
      XWiki.index.displayAttachmentEntry = function (row, i, table) {
        var inaccessibleDocs = false;
        if(row.acclev == true) {
          var fileLink = new Element('a', {'href' : row.fileurl}).update(row.filename);
          var tr = new Element('tr').update(new Element('td').update(fileLink));
          var pageLink = new Element('a', {'href' : row.url}).update(row.page);
          tr.appendChild(new Element('td', {'class' : 'pagename'}).update(pageLink));
          var spaceLink = new Element('a', {'href' : row.spaceurl}).update(row.space);
          tr.appendChild(new Element('td', {'class' : 'spacename'}).update(spaceLink));
          tr.appendChild(new Element('td').update(row.date));
          var aa = new Element('a', {'href' : row.authorurl}).update(row.authorname);
          tr.appendChild(new Element('td').update(aa));
          var type = new Element('td').update(getMimeTypeImage(row.type));
          tr.appendChild(type);
      
          if(row.filesize) {
             var filesizeBytes = row.filesize;
             var largeAttachment = filesizeBytes > (1048576 * 3);
             
             var filesizeStr = filesizeBytes > 1048576 ? (Math.round(filesizeBytes / 1048576)).toFixed(0) + " MB" : (filesizeBytes / 1024).toFixed(1) + " KB"
             
             var filesizeTd = largeAttachment ? new Element('td',{'style':'color:red;'}) : new Element('td')
             filesizeTd.update(filesizeStr);
            
             tr.appendChild(filesizeTd);
          }
              
          return tr;
        } else {
          var tr = new Element('tr');
          var page = row.fullname;
      
          var td1 = new Element('td').update("unavailable");
          var td2 = new Element('td', {'class' : 'pagename'}).update(page + "*");
          var td3 = new Element('td').update(" ");
          var td4 = new Element('td').update(" ");
          var td5 = new Element('td').update(" ");
          var td6 = new Element('td').update(" ");
          var td7 = new Element('td').update(" ");
          tr.appendChild(td1);
          tr.appendChild(td2);
          tr.appendChild(td3);
          tr.appendChild(td4);
          tr.appendChild(td5);
          tr.appendChild(td6);
          if(row.filesize) {
             tr.appendChild(td7);
          }
          $('inaccessibleDocsMessage').removeClassName('hidden');
          return tr;
        }
      }
      
      })();
      
      
      

      XWiki.AllAttachments: (editor)

      {{velocity}}
      #set ($discard = $xwiki.jsx.use('XWiki.AllAttachments'))
      ##
      #set ($collist = ['filename', 'doc.name', 'doc.space', 'date', 'author', 'type','filesize'])
      #set ($colprops = {
                         'filename'  : { 'type' : 'text', 'size' : 10 },
                         'doc.name'  : { 'type' : 'text', 'size' : 10 },
                         'doc.space' : { 'type' : 'text', 'size' : 10 },
                         'date'      : { 'type' : 'date', 'size' : 10, 'filterable' : false },
                         'author'    : { 'type' : 'text', 'size' : 10 },
                         'type'      : { 'sortable' : false },
                         'filesize'    : { 'displayName' : 'File Size', 'size' : 10 }
                       })
      #set($options = { 'url' : $xwiki.getURL('XWiki.AllAttachmentsResults', 'get', 'xpage=plain&outputSyntax=plain'),
                        'callback' : 'XWiki.index.displayAttachmentEntry',
                        'translationPrefix' : 'platform.index.attachments.' })
      #livetable('allattachments' $collist $colprops $options)
      
      (% id="inaccessibleDocsMessage" class="hidden" %)
      (((
      {{info}}$msg.get('rightsmanager.documentrequireviewrights'){{/info}}
      )))
      {{/velocity}}
      
      

      XWiki.AllAttachmentsResults:

      {{velocity wiki="false"}}
      ## ============================================================================================
      ## This page is called from live grids via Ajax with the argument xpage=plain. It returns a
      ## set of results serialized in JSON.
      ## @programming This service page needs to be saved by a user with the programming access level
      ## to work as expected
      ## ============================================================================================
      #if ("$!request.get('xpage')" == 'plain')
        $response.setContentType('application/json')##
        #set ($offset = $util.parseInt($request.get('offset')))
        ## offset starts from 0 in velocity and 1 in javascript
        #set ($off = $offset - 1)
        #set ($limit = $util.parseInt($request.get('limit')))
        #set ($title = $request.get('doc.name'))
        #set ($author = $request.get('author'))
        #set ($space = $request.get('doc.space'))
        #set ($filename = $request.filename)
        #set ($formatDate = 'yyyy MMMM dd, HH:mm')
        #set ($query = '')
        #set ($queryParameters = [])
        #if ($title)
          #set ($title = $title.trim().toLowerCase())
          #set ($query = $query + " and lower(doc.name) like ?")
          #set ($discard = $queryParameters.add("%${title}%"))
        #end
        #if ($author)
          #set ($author = $author.trim().toLowerCase())
          #set ($query = $query + " and lower(attach.author) like ?")
          #set ($discard = $queryParameters.add("%${author}%"))
        #end
        #if ($filename)
          #set ($filename = $filename.trim().toLowerCase())
          #set ($query = $query + " and lower(attach.filename) like ?")
          #set ($discard = $queryParameters.add("%${filename}%"))
        #end
        #if ($space)
          #set ($space = $space.trim().toLowerCase())
          #set ($query = $query + " and lower(doc.space) like ?")
          #set ($discard = $queryParameters.add("%${space}%"))
        #end
        ##
        ## Exclude Blacklisted spaces ($blacklistedSpaces is set in xwikivars.vm)
        ##
        #if (!$hasAdmin)
          #foreach ($blacklistedSpace in $blacklistedSpaces)
            #set ($query = "${query} and doc.space <> ?")
            #set ($discard = $queryParameters.add($blacklistedSpace))
          #end
        #end
        #set ($validSortOptions = ['filename', 'doc.name', 'doc.space', 'date', 'author','filesize'])
        #if ($validSortOptions.contains($request.sort))
          #set ($order = $request.sort)
        #else
          #set ($order = 'filename')
        #end 
        #if (!$order.startsWith('doc.'))
          #set ($order = "attach.${order}")
        #end  
        #if ("$!request.dir" == 'desc')
          #set ($dir = 'desc')
        #else
          #set ($dir = 'asc')
        #end
        ##
        ## Compute the final query
        ##
        #set ($countQuery = "select count(*) from XWikiDocument as doc, XWikiAttachment as attach where attach.docId=doc.id" + $query)
        #set ($query = "select doc.fullName, attach from XWikiDocument as doc, XWikiAttachment as attach where attach.docId=doc.id" + $query + " order by $order $dir")
        #set ($items = $xwiki.search($query, $limit, $off, $queryParameters))
        #set ($totalItems = $xwiki.search($countQuery, 0, 0, $queryParameters).get(0))
        #set ($returnedItems = $items.size())
        ## ==============================================
        ## json starts
        ## ==============================================
      {
      "totalrows": $totalItems,
      "returnedrows": #if($returnedItems < $limit) $returnedItems #else $limit #end,
      "offset": $offset,
      "reqNo": $util.parseInt($request.reqNo),
      "rows": [
      #foreach ($item in $items)
        #set ($docName = $item.get(0))
        #set ($hasAccess = $xwiki.hasAccessLevel('view', $context.user, $docName))
        #set ($attachment = $item.get(1))
        #if ($velocityCount > 1) , #end
        { "acclev" : $hasAccess,
        #if ($hasAccess)
          #set ($document = $xwiki.getDocument($docName))
          "page" : "$escapetool.javascript($document.name)",
          "space" : "$escapetool.javascript($document.space)",
          "fullname" : "$escapetool.javascript($document.fullName)",
          "filename" : "$escapetool.javascript($attachment.filename)",
          "fileurl" : "$document.getAttachmentURL($attachment.filename)",
          "url" : "$document.getURL('view')",
          "spaceurl" : "$xwiki.getURL("${document.space}.WebHome")",
          "date" : "$xwiki.formatDate($attachment.date, $formatDate)",
          "author" : "$!escapetool.javascript($attachment.author)",
          "authorname" : "$!escapetool.javascript($xwiki.getDocument($attachment.author).name)",
          "authorurl" : "$xwiki.getURL($attachment.author)",
          "type" : "$!escapetool.javascript($attachment.getMimeType($context.context))",
          "filesize" : "$!escapetool.javascript($attachment.getFilesize())"
        #else
          "fullname": "$escapetool.javascript($docName)"
        #end
        }
      #end
      ]}
      ## ==============================================
      ## json ended
      ## ==============================================
      #end
      {{/velocity}}
      
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                mflorea Marius Dumitru Florea
                Reporter:
                jamiem Jamie Maher
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: