Paket açma tar
ve zip
Windows kullanıcılarından aldığım dosyalar ile ilgili sorunlar yaşadım. "Çalışacak olan arşivin nasıl oluşturulacağı" sorusuna cevap vermeme rağmen , asıl işletim sisteminden bağımsız olarak aşağıdaki komut dosyaları doğru şekilde açılmaya tar
ve zip
dosyaları açmaya yardımcı olur .
UYARI: Bir ayarlamak için (kaynak el kodlayan sahiptir cp1251
, cp866
aşağıdaki örneklerde). Komut satırı seçenekleri gelecekte iyi bir çözüm olabilir.
Katran:
#!/usr/bin/env python
import tarfile
import codecs
import sys
def recover(name):
return codecs.decode(name, 'cp1251')
for tar_filename in sys.argv[1:]:
tar = tarfile.open(name=tar_filename, mode='r', bufsize=16*1024)
updated = []
for m in tar.getmembers():
m.name = recover(m.name)
updated.append(m)
tar.extractall(members=updated)
tar.close()
zip:
#!/usr/bin/env python
import zipfile
import os
import codecs
import sys
def recover(name):
return codecs.decode(name, 'cp866')
for filename in sys.argv[1:]:
archive = zipfile.ZipFile(filename, 'r')
infolist = archive.infolist()
for i in infolist:
f = recover(i.filename)
print f
if f.endswith("/"):
os.makedirs(os.path.dirname(f))
else:
open(f, 'w').write(archive.read(i))
archive.close()
UPD 2018-01-02 : chardet
Ham veri yığınının doğru kodlandığını tahmin etmek için paketi kullanıyorum . Şimdi senaryo, tüm kötü arşivlerimin yanı sıra, iyi olanların üstünde kutudan çıkıyor.
Dikkat edilecek şeyler:
- Kodlama tahmin motoru için metnin daha büyük bir parçasını yapmak üzere tüm dosya adları tek bir dizgeye eklenir ve birleştirilir. Bu, her biri farklı şekilde vidalanan az sayıda dosya adının, tahminde bozulmaya neden olabileceği anlamına gelir.
- İyi bir unicode metni işlemek için özel hızlı yol kullanıldı (
chardet
normal bir unicode nesnesiyle çalışmıyor).
- Teste eklenir ve normalleştiricinin oldukça kısa bir dizgideki kodlamaları tanıdığını göstermek için eklenir.
Son sürüm:
#!/usr/bin/env python2
# coding=utf-8
import zipfile
import os
import codecs
import sys
import chardet
def make_encoding_normalizer(txt):
u'''
Takes raw data and returns function to normalize encoding of the data.
* `txt` is either unicode or raw bytes;
* `chardet` library is used to guess the correct encoding.
>>> n_unicode = make_encoding_normalizer(u"Привет!")
>>> print n_unicode(u"День добрый")
День добрый
>>> n_cp1251 = make_encoding_normalizer(u"Привет!".encode('cp1251'))
>>> print n_cp1251(u"День добрый".encode('cp1251'))
День добрый
>>> type(n_cp1251(u"День добрый".encode('cp1251')))
<type 'unicode'>
'''
if isinstance(txt, unicode):
return lambda text: text
enc = chardet.detect(txt)['encoding']
return lambda file_name: codecs.decode(file_name, enc)
for filename in sys.argv[1:]:
archive = zipfile.ZipFile(filename, 'r')
infolist = archive.infolist()
probe_txt = "\n".join(i.filename for i in infolist)
normalizer = make_encoding_normalizer(probe_txt)
for i in infolist:
print i.filename
f = normalizer(i.filename)
print f
dirname = os.path.dirname(f)
if dirname:
assert os.path.abspath(dirname).startswith(os.path.abspath(".")), \
"Security violation"
if not os.path.exists(dirname):
os.makedirs(dirname)
if not f.endswith("/"):
open(f, 'w').write(archive.read(i))
archive.close()
if __name__ == '__main__' and len(sys.argv) == 1:
# Hack for Python 2.x to support unicode source files as doctest sources.
reload(sys)
sys.setdefaultencoding("UTF-8")
import doctest
doctest.testmod()
print "If there are no messages above, the script passes all tests."