উইন্ডোজ ব্যবহারকারীদের কাছ থেকে আনপ্যাক করা tar
এবং zip
ফাইলগুলি নিয়ে আমার সমস্যা হয়েছিল । আমি কীভাবে "সংরক্ষণাগারটি কীভাবে কাজ করবে তা তৈরি করা যায়" এই প্রশ্নের উত্তর না দিলেও নীচের স্ক্রিপ্টগুলি মূল ওএস নির্বিশেষে আনপ্যাক tar
এবং zip
ফাইলগুলি সঠিকভাবে আনতে সহায়তা করে ।
সর্তকতা: আর একবার সুর উৎস নিজে এনকোড করা (হয়েছে cp1251
, cp866
নিচের উদাহরণ মধ্যে)। কমান্ডলাইন বিকল্পগুলি ভবিষ্যতে একটি ভাল সমাধান হতে পারে।
আলকাতরা:
#!/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()
জিপ:
#!/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()
ইউপিডি 2018-01-02 : আমি chardet
ডেটার কাঁচা অংশের সঠিক এনকোডিং অনুমান করতে প্যাকেজটি ব্যবহার করি। এখন স্ক্রিপ্টটি আমার সমস্ত খারাপ সংরক্ষণাগারের পাশাপাশি বাক্স থেকে খুব ভালভাবে কাজ করে।
বিষয়গুলি নোট করুন:
- এনকোডিং অনুমান ইঞ্জিনের জন্য পাঠ্যের একটি বড় টুকরো তৈরি করতে সমস্ত ফাইলের নামগুলি একক স্ট্রিংয়ের সাথে উত্তোলন এবং একত্রীকরণ করা হয়। এর অর্থ হ'ল প্রতিটি ফাইল আলাদাভাবে স্ক্রু করা অনুমানটি নষ্ট করতে পারে।
- একটি ভাল ইউনিকোড পাঠ্য (
chardet
সাধারণ ইউনিকোড অবজেক্টের সাথে কাজ করে না) হ্যান্ডেল করার জন্য বিশেষ দ্রুতগামী পথ ব্যবহার করা হত ।
- নথিকে পরীক্ষার জন্য যুক্ত করা হয় এবং প্রদর্শিত হয় যে নরমালাইজার যুক্তিসঙ্গত সংক্ষিপ্ত স্ট্রিংগুলিতে যে কোনও এনকোডিংকে স্বীকৃতি দেয়।
চূড়ান্ত সংস্করণ:
#!/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."