Item copy

This implements an item copy rest call via /item/{} POST.  It adds test coverage for the new functions.  As part of this, I've added a method to the files model to copy a file.  For all of our current three asset stores, I've added code to allow multiple files to use the same data through the use of a repeated reference.
Python prior to 2.5 or 2.6 (I don't remember) was very bad at memory
management and speed with repeatedly concatenating strings.  It was vastly
better to make a list and then join it.  I know they improved this in
Python 2.7 and Python 3, but my habit is still to do the list and join as I
know that it is efficient.

On Mon, Sep 22, 2014 at 2:14 PM, Zach Mullen <notifications@github.com>
wrote:

> In tests/cases/item_test.py:
>
> > @@ -122,10 +122,20 @@ def _testDownloadMultiFileItem(self, item, user, contents):
> >          resp = self.request(path='/item/{}/download'.format(item['_id']),
> >                              method='GET', user=user, isJson=False)
> >          self.assertStatusOk(resp)
> > -        zipFile = zipfile.ZipFile(io.BytesIO(resp.collapse_body()), 'r')
> > +        # cherrypy doesn't collapse the body properly when unicode is mixed
> > +        # with binary data.  Instead of using
> > +        #  zipFile = zipfile.ZipFile(io.BytesIO(resp.collapse_body()), 'r')
> > +        # we have to generate the body ourselves.
> > +        body = []
> > +        for chunk in resp.body:
> > +            if isinstance(chunk, unicode):
> > +                chunk = chunk.encode("utf8")
> > +            body.append(chunk)
> > +        body = "".join(body)
>
> Why make a list and append and then join it? Could we just make a string
> and append to it? (Or is this by design to save on mem copy overhead?)
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/girder/girder/pull/337/files#r17866908>.
>