Set permissions on a compressed file in python

I have a file test.txt that is inside a zip archive test.zip. The permissions on test.txt are out of my control when it's compressed, but now I want them to be group-writeable. I am extracting the file with Python, and don't want to escape out to the shell.

EDIT: Here's what I've got so far:

import zipfile

z = zipfile.ZipFile('test.zip', 'w')
zi = zipfile.ZipInfo('test.txt')
zi.external_attr = 0777 << 16L
z.writestr(zi, 'FOO')
z.close()

z = zipfile.ZipFile('test.zip', 'r')
for name in z.namelist():
    newFile = open(name, "wb")
    newFile.write(z.read(name))

    newFile.close()
z.close()

This works perfectly on OS X using 2.5.1, but it doesn't work on my home box (Debian, Python 2.4 & 2.5) or on RHEL 5 with Python 2.4. On anything but OS X it doesn't error, but doesn't change the permissions either. Any ideas why? Also, how does writestr() work? I know I'm using it incorrectly here.

Is there a way to do this without os.chmod (the user extracting the file doesn't have permissions to use os.chmod after it's extracted)? I have full write access to the zip file.

More info:

> ls -l test.zip
-rwxrwxrwx 1 myuser mygroup 2008-11-11 13:24 test.zip
> unzip test.zip
Archive:  test.zip
  inflating: test.txt 
> ls -l test.txt
-rw-r--r-- 1 myuser mygroup 2008-11-11 13:34 test.txt

The user extracting is not myuser, but is in mygroup.


Asked by: Rubie494 | Posted: 01-10-2021






Answer 1

I had a similar problem to you, so here is the code spinet from my stuff, this I believe should help here.

# extract all of the zip
for file in zf.filelist:
    name = file.filename
    perm = ((file.external_attr >> 16L) & 0777)
    if name.endswith('/'):
        outfile = os.path.join(dir, name)
        os.mkdir(outfile, perm)
    else:
        outfile = os.path.join(dir, name)
        fh = os.open(outfile, os.O_CREAT | os.O_WRONLY , perm)
        os.write(fh, zf.read(name))
        os.close(fh)
    print "Extracting: " + outfile

You might do something similar, but insert your own logic to calculate your perm value. I should note that I'm using Python 2.5 here, I'm aware of a few incompatibilities with some versions of Python's zipfile support.

Answered by: Ryan406 | Posted: 02-11-2021



Answer 2

Per the documentation, unzip sets the permissions to those stored, under unix. Also, the shell umask is not used. Your best bet is to make sure the perms are set before you zip the file.

Since you can't do that, you will have to try and do what you were trying to do (and get it to work under Debian.)

There have been a number of issues with Pythons zipfile library, including setting the mode of writestr to that of the file being written on some systems, or setting the zip systm to windows instead of unix. So your inconsistent results may mean that nothing has changed.

So you may be completely out of luck.

Answered by: Lenny628 | Posted: 02-11-2021



Answer 3

@Petriborg's answer is still relevant, but to work with Python 3, here is a version with the necessary fixes:

import os
import zipfile

zip_file = "/path/to/archive.zip"
out_dir = "/path/to/output"

os.makedirs(out_dir, exist_ok=True)

with zipfile.ZipFile(zip_file, "r") as zf:
    for file in zf.filelist:
        name = file.filename
        perm = ((file.external_attr >> 16) & 0o777)
        print("Extracting: " + name)
        if name.endswith("/"):
            os.mkdir(os.path.join(out_dir, name), perm)
        else:
            outfile = os.path.join(out_dir, name)
            fh = os.open(outfile, os.O_CREAT | os.O_WRONLY, perm)
            os.write(fh, zf.read(name))
            os.close(fh)

Answered by: Tara706 | Posted: 02-11-2021



Answer 4

Extract to stdout (unzip -p) and redirect to a file? If there's more than one file in the zip, you could list the zip contents, and then extract one at a time.

for n in `unzip -l test.zip | awk 'NR > 3 && NF == 4 { print $4 }'`; do unzip -p test.zip $n > $n; done

(yeah, I know you tagged this 'python' :-) )

Answered by: Gianna675 | Posted: 02-11-2021



Similar questions

python - Will Django be a good choice for a permissions based web-app?

I've been exploring the details of Django for about a week now and like what I see. However I've come upon some.. negativity in relation to fine-grained control of permissions to the CRUD interface. What I'm writing is an Intranet client management web-app. The organisation is about 6 tiers, and I need to restrict access to client groups based on tiers. Continually expanding. I have a fairly good idea how I'm going...


python - Amazon S3 permissions

Trying to understand S3...How do you limit access to a file you upload to S3? For example, from a web application, each user has files they can upload, but how do you limit access so only that user has access to that file? It seems like the query string authentication requires an expiration date and that won't work for me, is there another way to do this?


chmod - check permissions of directories in python

i want a python program that given a directory, it will return all directories within that directory that have 775 (rwxrwxr-x) permissions thanks!


python - Permissions for a site only

I have a multilingual Django project. Every language is a different subdomain. So we've decided to use the "sites" application and to create one different site for every language. On that project, I also have a "pages" application, which is quite similar to a CMS. The user can create pages with content and they'll be displayed in the appropriate language site. Now I'm looking to be able to manage advanced p...


python - DB Permissions with Django unit testing

Disclaimer: I'm very new to Django. I must say that so far I really like it. :) (now for the "but"...) But, there seems to be something I'm missing related to unit testing. I'm working on a new project with an Oracle backend. When you run the unit tests, it immediately gives a permissions error when trying to create the schema. So, I get what it's trying to do (create a clean sandbox), but what...


python - How do I change permissions to a socket?

I am trying to run a simple Python based web server given here. And I get the following error message: Traceback (most recent call last): File "webserver.py", line 63, in &lt;module&gt; main() File "webserver.py", line 55, in main server = HTTPServer(('', 80), MyHandler) File "/usr/lib/python2.5/SocketSe...


linux - Dropping Root Permissions In Python

I'd like to have a Python program start listening on port 80, but after that execute without root permissions. Is there a way to drop root or to get port 80 without it?


setting permissions of python module (python setup install)

I am configuring a distutils-based setup.py for a python module that is to be installed on a heterogeneous set of resources. Due to the heterogeneity, the location where the module is installed is not the same on each host however disutils picks the host-specific location. I find that the module is installed without o+rx permissions using disutils (in spite of setting umask ahead of running setup.py). One solutio...


python - Django 1.2 object level permissions - third party solutions?


python - Django Inlines user permissions + view only - permissions issues

I'm not sure if this is a bug or I'm just missing something (although I have already parsed the documentation about inlines), but: Let's say I have a model A. Model A is an inline of model B. User U has full access to model B, but only change permissions to model A (so, no add, nor delete). However, when editing model B, user U can still see the "Add another A" link at the bottom, although U hasn't add perm...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top