Извлечение .app из zip-файла в Python с использованием ZipFile - PullRequest
2 голосов
/ 28 мая 2010

Я пытаюсь извлечь новые версии Chromium.app из их снимков, и я могу нормально загрузить файл, но когда дело доходит до его извлечения, ZipFile либо извлекает папку chrome-mac внутри как файл, говорит, что каталоги не существуют и т. д. Я очень плохо знаком с Python, поэтому эти ошибки мало что значат для меня. Вот что у меня есть.

import urllib2
response = urllib2.urlopen('http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/LATEST')
latestRev = response.read()
print latestRev

# we have the revision, now we need to download the zip and extract it
latestZip = urllib2.urlopen('http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/%i/chrome-mac.zip' % (int(latestRev)), '~/Desktop/ChromiumUpdate/%i-update' % (int(latestRev)))
#declare some vars that hold paths n shit
workingDir = '/Users/slehan/Desktop/ChromiumUpdate/'
chromiumZipPath = '%s%i-update.zip' % (workingDir, (int(latestRev)))
chromiumAppPath = 'chrome-mac/' #the path of the chromium executable within the zip file
chromiumAppExtracted = '%s/Chromium.app' % (workingDir) # path of the extracted executable

output = open(chromiumZipPath, 'w') #delete any current file there
output.write(latestZip.read())
output.close()

# we have the .zip now we need to extract the Chromium.app file, it's in ziproot/chrome-mac/Chromium.app
import zipfile, os
zippedFile = open(chromiumZipPath)
zippedChromium = zipfile.ZipFile(zippedFile, 'r')
zippedChromium.extract(chromiumAppPath, workingDir)
#print zippedChromium.namelist()

zippedChromium.close()
#zippedChromium.close()

Есть идеи?

Ответы [ 4 ]

4 голосов
/ 29 мая 2010

Кажется, вы столкнулись с ошибкой в Python . Этот другой вопрос подробно описывает проблему и обходные пути. Вы можете выбрать один из этих обходных путей или обновить его до Python 2.6.5 или 2.7b2.

Один из обходных путей предлагает скопировать исправленный модуль zipfile.py из исправленного Python.

Удачи!

0 голосов
/ 18 марта 2019

Существует еще одна проблема при извлечении .app из zip-файла в Python (чего не происходит с обычной утилитой zip). Никто другой, кажется, не упомянул об этом ...

.app может перестать функционировать после извлечения таким образом в результате потери бита разрешения на выполнение во вложенном двоичном файле. Вы можете исправить это, просто предоставив это снова.

Вот свободный фрагмент кода, который я использую. Пересмотрите это по мере необходимости для ваших целей (или напишите более общую функцию для более универсального решения этой ситуации):

import os, zipfile
...
ZIP_PATH     = APP_PATH + ".zip" 
APP_BIN_DIR  = os.path.join( APP_PATH, "Contents/MacOS" )
zipfile.ZipFile( ZIP_PATH, 'r' ).extractall( WORK_DIR )   
BIN_PATH = os.path.join( APP_BIN_DIR, os.listdir( APP_BIN_DIR )[0] )
os.chmod( BIN_PATH, 0o777 )

Моя программа уже знала, где ожидать, что будет найдено APP_PATH (то есть в пределах WORK_DIR). Я должен был застегнуть это, хотя, и заносить эту деталь после факта. Я называю свой почтовый индекс как XXXXX.app.zip. Я разрешаю BIN_PATH здесь довольно просто, без необходимости знать имя двоичного файла внутри .app, потому что я знаю, что в моем случае будет только один файл Я даю ему полные (777) разрешения, потому что я все равно просто удаляю .app в конце своего скрипта.

0 голосов
/ 28 мая 2010

Вот еще один разрез - это та же техника, но она показывает результаты, чтобы продемонстрировать, что она работает.

import os
import urllib2
import zipfile
from StringIO import StringIO

response = urllib2.urlopen('http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/LATEST')
latestRev = response.read()
print 'getting revision', latestRev

# we have the revision, now we need to download the zip and extract it
locRef='http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/%i/chrome-mac.zip' % (int(latestRev))
latestZip = StringIO(urllib2.urlopen(locRef).read())

# we have the .zip now we need to extract the Chromium.app file, it's in chrome-mac/Chromium.app/
zippedChromium = zipfile.ZipFile(latestZip)
# find all zip members in chrome-mac/Chromium.app
members = [m for m in zippedChromium.namelist() if m.startswith('chrome-mac/Chromium.app/')]
#zippedChromium.extract(chromiumAppPath, workingDir)
target = 'chromium-%s' % latestRev
if os.path.isdir(target):
    print 'destination already exists, exiting'
    raise SystemExit(1)
os.makedirs(target)
zippedChromium.extractall(target, members)

lengths = [
    (len(dirnames), len(filenames))
    for dirpath, dirnames, filenames in os.walk(target)
    ]
dirlengths, filelengths = zip(*lengths)
ndirs = sum(dirlengths)
nfiles = sum(filelengths)
print 'extracted %(nfiles)d files in %(ndirs)d dirs' % vars()
#zippedChromium.close()

Вывод, который я получаю при запуске,

> .\getapp.py
getting revision 48479
extracted 537 files in 184 dirs
0 голосов
/ 28 мая 2010

Мне кажется, это работает:

import os
import urllib2
import zipfile
from StringIO import StringIO

response = urllib2.urlopen('http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/LATEST')
latestRev = response.read()
print 'getting revision', latestRev

# we have the revision, now we need to download the zip and extract it
locRef='http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/%i/chrome-mac.zip' % (int(latestRev))
latestZip = StringIO(urllib2.urlopen(locRef).read())

# we have the .zip now we need to extract the Chromium.app file, it's in chrome-mac/Chromium.app/
zippedChromium = zipfile.ZipFile(latestZip)
# find all zip members in chrome-mac/Chromium.app
members = [m for m in zippedChromium.namelist() if m.startswith('chrome-mac/Chromium.app/')]
#zippedChromium.extract(chromiumAppPath, workingDir)
target = 'chromium-%s' % latestRev
if os.path.isdir(target):
    print 'destination already exists, exiting'
    raise SystemExit(1)
os.makedirs(target)
zippedChromium.extractall(target, members)

#zippedChromium.close()
...