-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathcreateArchive.py
119 lines (99 loc) · 4.57 KB
/
createArchive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import os
import time
import traceback
import libarchive
from lib.FileManager.FM import REQUEST_DELAY
from lib.FileManager.workers.baseWorkerCustomer import BaseWorkerCustomer
class CreateArchive(BaseWorkerCustomer):
def __init__(self, params, *args, **kwargs):
super(CreateArchive, self).__init__(*args, **kwargs)
self.path = params.get('path')
self.type = params.get('type', 'zip')
self.file_items = params.get('files', [])
self.params = params
def run(self):
try:
self.preload()
abs_archive_path = self.get_abs_path(self.path)
dir_name = os.path.dirname(abs_archive_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
if not os.path.isdir(dir_name):
raise Exception("Destination path is not a directory")
archive_type = self.get_archive_type(self.type)
if not archive_type:
raise Exception("Unknown archive type")
archive_path = abs_archive_path + "." + archive_type
if os.path.exists(archive_path):
raise Exception("Archive file already exist")
self.on_running(self.status_id, pid=self.pid, pname=self.name)
archive = libarchive.Archive(archive_path, "w")
next_tick = time.time() + REQUEST_DELAY
i = 0
for file_item in self.file_items:
try:
abs_path = self.get_abs_path(file_item.get("path"))
file_basename = os.path.basename(abs_path)
if os.path.isfile(abs_path):
self.logger.info("Packing file: %s" % (abs_path,))
f = open(abs_path, 'rb')
archive.write(self.make_entry(abs_path, file_basename), data=f.read())
f.close()
elif os.path.isdir(abs_path):
self.logger.info("Packing dir: %s" % (abs_path,))
for current, dirs, files in os.walk(abs_path):
for f in files:
file_path = os.path.join(current, f)
file_obj = open(file_path, 'rb')
rel_path = os.path.relpath(file_path, abs_path)
base_path = os.path.join(file_basename, rel_path)
archive.write(self.make_entry(file_path, base_path), data=file_obj.read())
file_obj.close()
i += 1
if time.time() > next_tick:
progress = {
'percent': round(float(i) / float(len(self.file_items)), 2),
'text': str(int(round(float(i) / float(len(self.file_items)), 2) * 100)) + '%'
}
self.on_running(self.status_id, progress=progress, pid=self.pid, pname=self.name)
next_tick = time.time() + REQUEST_DELAY
except Exception as e:
self.logger.error(
"Error archive file %s , error %s , %s" % (str(file_item), str(e), traceback.format_exc()))
raise e
progress = {
'percent': round(float(i) / float(len(self.file_items)), 2),
'text': str(int(round(float(i) / float(len(self.file_items)), 2) * 100)) + '%'
}
result = {
"archive": self._make_file_info(archive_path)
}
self.on_success(self.status_id, data=result, progress=progress, pid=self.pid, pname=self.name)
except Exception as e:
result = {
"error": True,
"message": str(e),
"traceback": traceback.format_exc()
}
self.on_error(self.status_id, result, pid=self.pid, pname=self.name)
@staticmethod
def get_archive_type(extension):
archive_type = False
if extension == 'zip':
archive_type = 'zip'
elif extension == 'gzip':
archive_type = 'tar.gz'
elif extension == 'bz2':
archive_type = 'tar.bz2'
elif extension == 'tar':
archive_type = 'tar'
return archive_type
@staticmethod
def make_entry(f, base_path):
entry = libarchive.Entry(encoding='utf-8')
st = os.stat(f)
entry.pathname = base_path
entry.size = st.st_size
entry.mtime = st.st_mtime
entry.mode = st.st_mode
return entry