1 | """ |
||
2 | Copyright George Sibble 2018 |
||
3 | """ |
||
4 | 1 | from io import BytesIO |
|
5 | 1 | from ..utilities import b2_url_encode, b2_url_decode, decode_error |
|
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||
6 | 1 | from ..b2_exceptions import B2Exception |
|
7 | 1 | from ..api import API |
|
8 | |||
9 | 1 | class B2File(object): |
|
0 ignored issues
–
show
|
|||
10 | """ |
||
11 | |||
12 | """ |
||
13 | 1 | def __init__(self, connector, parent_list, fileId, fileName, contentSha1, contentLength, contentType, |
|
0 ignored issues
–
show
|
|||
14 | fileInfo, action, uploadTimestamp, *args, **kwargs): |
||
15 | """ |
||
16 | |||
17 | :param connector: |
||
18 | :param parent_list: |
||
19 | :param fileId: |
||
20 | :param fileName: |
||
21 | :param contentSha1: |
||
22 | :param contentLength: |
||
23 | :param contentType: |
||
24 | :param fileInfo: |
||
25 | :param action: |
||
26 | :param uploadTimestamp: |
||
27 | :param args: |
||
28 | :param kwargs: |
||
29 | """ |
||
30 | 1 | self.file_id = fileId |
|
31 | # self.file_name_decoded = b2_url_decode(fileName) |
||
32 | #TODO: Find out if this is necessary |
||
0 ignored issues
–
show
|
|||
33 | 1 | self.file_name = fileName |
|
34 | 1 | self.content_sha1 = contentSha1 |
|
35 | 1 | self.content_length = contentLength |
|
36 | 1 | self.content_type = contentType |
|
37 | 1 | self.file_info = fileInfo |
|
38 | 1 | self.action = action |
|
39 | 1 | self.uploadTimestamp = uploadTimestamp |
|
0 ignored issues
–
show
The name
uploadTimestamp does not conform to the attribute naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. ![]() |
|||
40 | 1 | self.connector = connector |
|
41 | 1 | self.parent_list = parent_list |
|
42 | 1 | self.deleted = False |
|
43 | |||
44 | 1 | def get_versions(self, limit=None): |
|
0 ignored issues
–
show
|
|||
45 | """ Fetch list of all versions of the current file. |
||
46 | Params: |
||
47 | limit: (int) Limit number of results returned (optional, default 10000) |
||
48 | |||
49 | Returns: |
||
50 | file_versions (list) B2FileObject of all file versions |
||
51 | """ |
||
52 | 1 | bucket_id = self.parent_list.bucket.bucket_id |
|
53 | |||
54 | 1 | path = API.list_file_versions |
|
55 | 1 | file_versions = [] |
|
56 | 1 | params = { |
|
57 | 'bucketId': bucket_id, |
||
58 | 'maxFileCount': limit or 10000, |
||
59 | 'startFileId': self.file_id, |
||
60 | 'startFileName': self.file_name, |
||
61 | } |
||
62 | |||
63 | 1 | response = self.connector.make_request(path=path, method='post', params=params) |
|
64 | 1 | if response.status_code == 200: |
|
65 | 1 | files_json = response.json() |
|
66 | 1 | for file_json in files_json['files']: |
|
67 | 1 | new_file = B2File(connector=self.connector, parent_list=self, **file_json) |
|
68 | 1 | file_versions.append(new_file) |
|
69 | else: |
||
70 | raise B2Exception.parse(response) |
||
71 | 1 | return file_versions |
|
72 | |||
0 ignored issues
–
show
|
|||
73 | |||
74 | 1 | def hide(self): |
|
75 | """ Soft-delete a file (hide it from files list, but previous versions are saved.) """ |
||
76 | 1 | path = API.delete_file |
|
77 | 1 | params = { |
|
78 | 'bucketId': self.parent_list.bucket.bucket_id, |
||
79 | 'fileName': b2_url_encode(self.file_name) |
||
80 | } |
||
81 | 1 | response = self.connector.make_request(path=path, method='post', params=params) |
|
82 | 1 | if response.status_code == 200: |
|
83 | 1 | self.deleted = True |
|
84 | # Delete from parent list if exists |
||
85 | 1 | self.parent_list._files_by_name.pop(self.file_name) |
|
0 ignored issues
–
show
It seems like
_files_by_name was declared protected and should not be accessed from this context.
Prefixing a member variable class MyParent:
def __init__(self):
self._x = 1;
self.y = 2;
class MyChild(MyParent):
def some_method(self):
return self._x # Ok, since accessed from a child class
class AnotherClass:
def some_method(self, instance_of_my_child):
return instance_of_my_child._x # Would be flagged as AnotherClass is not
# a child class of MyParent
![]() |
|||
86 | 1 | self.parent_list._files_by_id.pop(self.file_id) |
|
0 ignored issues
–
show
It seems like
_files_by_id was declared protected and should not be accessed from this context.
Prefixing a member variable class MyParent:
def __init__(self):
self._x = 1;
self.y = 2;
class MyChild(MyParent):
def some_method(self):
return self._x # Ok, since accessed from a child class
class AnotherClass:
def some_method(self, instance_of_my_child):
return instance_of_my_child._x # Would be flagged as AnotherClass is not
# a child class of MyParent
![]() |
|||
87 | else: |
||
88 | raise B2Exception.parse(response) |
||
89 | |||
90 | |||
91 | 1 | def delete_all_versions(self, confirm=False): |
|
92 | """ Delete completely all versions of a file. |
||
0 ignored issues
–
show
|
|||
93 | ** NOTE THAT THIS CAN BE VERY EXPENSIVE IN TERMS OF YOUR API LIMITS ** |
||
94 | Each call to delete_all_versions will result in multiple API calls: |
||
0 ignored issues
–
show
|
|||
95 | One API call per file version to be deleted, per file. |
||
96 | 1. Call '/b2_list_file_versions' to get file versions |
||
97 | 2. Call '/b2_delete_file_version' once for each version of the file |
||
98 | |||
99 | This means: if you have 10 files with 50 versions each and call delete_all_versions, |
||
0 ignored issues
–
show
|
|||
100 | you will spend (10 + 1) x 50 == 550 API calls against your BackBlaze b2 API limit. |
||
101 | |||
102 | ** You have been warned! BE CAREFUL!!! ** |
||
103 | """ |
||
104 | 1 | print(self.delete_all_versions.__name__, self.delete_all_versions.__doc__) # Print warnings at call time. |
|
0 ignored issues
–
show
|
|||
105 | |||
106 | # Confirm deletion |
||
107 | 1 | if not confirm: |
|
108 | print('To call this function, use delete_all_versions(confirm=True)') |
||
0 ignored issues
–
show
|
|||
109 | return False |
||
110 | |||
111 | 1 | versions = self.get_versions() |
|
112 | |||
113 | 1 | version_count = len(versions) |
|
114 | 1 | if not version_count > 0: |
|
115 | print('No file versions') |
||
0 ignored issues
–
show
|
|||
116 | else: |
||
117 | 1 | print(version_count, 'file versions') |
|
118 | 1 | for count, v in enumerate(versions): |
|
0 ignored issues
–
show
The name
v does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. ![]() |
|||
119 | 1 | print('deleting [{}/{}]'.format(count + 1 , version_count)) |
|
0 ignored issues
–
show
|
|||
120 | 1 | v.delete() |
|
121 | |||
122 | |||
123 | 1 | def delete(self): |
|
124 | """ Delete a file version (Does not delete entire file history: only most recent version) """ |
||
0 ignored issues
–
show
|
|||
125 | 1 | path = API.delete_file_version |
|
126 | 1 | params = { |
|
127 | 'fileId': self.file_id, |
||
128 | 'fileName': b2_url_encode(self.file_name) |
||
129 | } |
||
130 | 1 | response = self.connector.make_request(path=path, method='post', params=params) |
|
131 | 1 | if not response.status_code == 200: |
|
132 | raise B2Exception.parse(response) |
||
133 | 1 | self.deleted = True |
|
134 | |||
135 | |||
136 | 1 | def download(self): |
|
137 | """ Download latest file version """ |
||
138 | 1 | response = self.connector.download_file(file_id=self.file_id) |
|
139 | 1 | if response.status_code == 200: |
|
140 | 1 | return BytesIO(response.content) |
|
141 | else: |
||
142 | raise B2Exception.parse(response) |
||
143 | |||
144 | 1 | @property |
|
145 | def url(self): |
||
146 | """ Return file download URL """ |
||
147 | return self.connector.download_url + '?fileId=' + self.file_id |
||
148 |