xlwings-utils 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xlwings-utils might be problematic. Click here for more details.
- xlwings_utils/xlwings_utils.py +180 -84
- {xlwings_utils-0.0.2.dist-info → xlwings_utils-0.0.4.dist-info}/METADATA +1 -1
- xlwings_utils-0.0.4.dist-info/RECORD +6 -0
- xlwings_utils-0.0.2.dist-info/RECORD +0 -6
- {xlwings_utils-0.0.2.dist-info → xlwings_utils-0.0.4.dist-info}/WHEEL +0 -0
- {xlwings_utils-0.0.2.dist-info → xlwings_utils-0.0.4.dist-info}/top_level.txt +0 -0
xlwings_utils/xlwings_utils.py
CHANGED
|
@@ -5,19 +5,33 @@
|
|
|
5
5
|
# /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
|
|
6
6
|
# |___/ |_____|
|
|
7
7
|
|
|
8
|
-
__version__ = "0.0.
|
|
8
|
+
__version__ = "0.0.4"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
import dropbox
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
import
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
class BlockRange:
|
|
16
|
+
@property
|
|
17
|
+
def block(self):
|
|
18
|
+
return block(self.value)
|
|
19
|
+
|
|
20
|
+
@block.setter
|
|
21
|
+
def block(self, block):
|
|
22
|
+
self.value=block.as_list_of_lists
|
|
23
|
+
try:
|
|
24
|
+
import xlwings
|
|
25
|
+
xlwings.Range.block=BlockRange
|
|
26
|
+
except ImportError:
|
|
27
|
+
...
|
|
14
28
|
|
|
15
29
|
_captured_stdout = []
|
|
16
30
|
dbx = None
|
|
17
31
|
|
|
18
32
|
|
|
19
|
-
def dropbox_init(refresh_token, app_key, app_secret):
|
|
20
|
-
|
|
33
|
+
def dropbox_init(refresh_token=None, app_key=None, app_secret=None):
|
|
34
|
+
"""
|
|
21
35
|
dropbox initialize
|
|
22
36
|
|
|
23
37
|
This function has to be called prior to using any dropbox function
|
|
@@ -26,45 +40,59 @@ def dropbox_init(refresh_token, app_key, app_secret):
|
|
|
26
40
|
----------
|
|
27
41
|
refresh_token : str
|
|
28
42
|
oauth2 refreshntoken
|
|
29
|
-
|
|
43
|
+
|
|
44
|
+
if omitted: use the environment variable REFRESH_TOKEN
|
|
45
|
+
|
|
30
46
|
app_key : str
|
|
31
47
|
app key
|
|
32
|
-
|
|
48
|
+
|
|
49
|
+
if omitted: use the environment variable APP_KEY
|
|
50
|
+
|
|
51
|
+
|
|
33
52
|
app_secret : str
|
|
34
53
|
app secret
|
|
35
54
|
|
|
55
|
+
if omitted: use the environment variable APP_SECRET
|
|
36
56
|
|
|
37
57
|
Returns
|
|
38
58
|
-------
|
|
39
59
|
-
|
|
40
|
-
|
|
60
|
+
"""
|
|
61
|
+
if refresh_token is None:
|
|
62
|
+
refresh_token = os.environ["REFRESH_TOKEN"]
|
|
63
|
+
if app_key is None:
|
|
64
|
+
app_key = os.environ["APP_KEY"]
|
|
65
|
+
if app_secret is None:
|
|
66
|
+
app_secret = os.environ["APP_SECRET"]
|
|
67
|
+
|
|
41
68
|
global dbx
|
|
42
69
|
dbx = dropbox.Dropbox(oauth2_refresh_token=refresh_token, app_key=app_key, app_secret=app_secret)
|
|
43
|
-
|
|
70
|
+
|
|
71
|
+
|
|
44
72
|
def _check_dbx():
|
|
45
73
|
if dbx is None:
|
|
46
|
-
raise ValueError(
|
|
74
|
+
raise ValueError("not initialized. Please call dropbox_init()")
|
|
47
75
|
|
|
48
76
|
|
|
49
77
|
def list_dropbox(path="", recursive=False):
|
|
50
|
-
|
|
78
|
+
"""
|
|
51
79
|
list_dropbox
|
|
52
|
-
|
|
80
|
+
|
|
53
81
|
returns all dropbox files in path
|
|
54
|
-
|
|
82
|
+
|
|
55
83
|
Parameters
|
|
56
84
|
----------
|
|
57
85
|
path : str or Pathlib.Path
|
|
58
86
|
path from which to list all files (default: '')
|
|
59
|
-
|
|
60
|
-
|
|
87
|
+
|
|
88
|
+
|
|
61
89
|
recursive : bool
|
|
62
90
|
if True, recursively list files. if False (default) no recursion
|
|
63
|
-
|
|
91
|
+
|
|
64
92
|
Returns
|
|
65
93
|
-------
|
|
66
94
|
files, relative to path : list
|
|
67
|
-
|
|
95
|
+
"""
|
|
68
96
|
_check_dbx()
|
|
69
97
|
out = []
|
|
70
98
|
result = dbx.files_list_folder(path, recursive=recursive)
|
|
@@ -83,20 +111,20 @@ def list_dropbox(path="", recursive=False):
|
|
|
83
111
|
|
|
84
112
|
|
|
85
113
|
def read_dropbox(dropbox_path):
|
|
86
|
-
|
|
114
|
+
"""
|
|
87
115
|
read_dropbox
|
|
88
|
-
|
|
116
|
+
|
|
89
117
|
read from dopbox at given path
|
|
90
|
-
|
|
118
|
+
|
|
91
119
|
Parameters
|
|
92
120
|
----------
|
|
93
|
-
|
|
121
|
+
dropbox_path : str or Pathlib.Path
|
|
94
122
|
path to read from
|
|
95
|
-
|
|
123
|
+
|
|
96
124
|
Returns
|
|
97
125
|
-------
|
|
98
126
|
contents of the dropbox file : bytes
|
|
99
|
-
|
|
127
|
+
"""
|
|
100
128
|
|
|
101
129
|
_check_dbx()
|
|
102
130
|
metadata, response = dbx.files_download(dropbox_path)
|
|
@@ -106,81 +134,177 @@ def read_dropbox(dropbox_path):
|
|
|
106
134
|
|
|
107
135
|
def write_dropbox(dropbox_path, contents):
|
|
108
136
|
_check_dbx()
|
|
137
|
+
"""
|
|
138
|
+
write_dropbox
|
|
139
|
+
|
|
140
|
+
write from dopbox at given path
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
dropbox_path : str or Pathlib.Path
|
|
145
|
+
path to write to
|
|
146
|
+
|
|
147
|
+
contents : bytes
|
|
148
|
+
contents to be written
|
|
149
|
+
|
|
150
|
+
"""
|
|
109
151
|
dbx.files_upload(contents, dropbox_path, mode=dropbox.files.WriteMode.overwrite)
|
|
110
152
|
|
|
111
153
|
|
|
112
|
-
def
|
|
154
|
+
def list_local(path):
|
|
113
155
|
path = Path(path)
|
|
114
156
|
return list(path.iterdir())
|
|
115
157
|
|
|
116
158
|
|
|
117
|
-
def
|
|
159
|
+
def write_local(path, contents):
|
|
118
160
|
path = Path(path)
|
|
119
161
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
120
162
|
with open(path, "wb") as f:
|
|
121
163
|
f.write(contents)
|
|
122
164
|
|
|
123
165
|
|
|
124
|
-
def
|
|
166
|
+
def read_local(path):
|
|
125
167
|
path = Path(path)
|
|
126
168
|
with open(path, "rb") as f:
|
|
127
169
|
contents = f.read()
|
|
128
170
|
return contents
|
|
129
171
|
|
|
172
|
+
|
|
130
173
|
class block:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
174
|
+
"""
|
|
175
|
+
block is 2 dimensional with 1 as lowest index (like xlwings range) data structure
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
number_of_rows : int
|
|
180
|
+
number of rows
|
|
181
|
+
|
|
182
|
+
number_of_columns : int
|
|
183
|
+
number of columns
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
block
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
def __init__(self, number_of_rows, number_of_columns):
|
|
191
|
+
self.dict = {}
|
|
192
|
+
self.number_of_columns = number_of_columns
|
|
193
|
+
self.number_of_rows = number_of_rows
|
|
135
194
|
|
|
136
195
|
@classmethod
|
|
137
196
|
def from_list_of_lists(cls, list_of_lists, column_like=False):
|
|
138
|
-
|
|
197
|
+
"""
|
|
198
|
+
from_list_of_lists
|
|
199
|
+
|
|
200
|
+
Parameters
|
|
201
|
+
----------
|
|
202
|
+
list_of_lists : list of lists
|
|
203
|
+
to be used to fill the block
|
|
204
|
+
|
|
205
|
+
columns_like : bool
|
|
206
|
+
if False (default), one dimenional lists will be treated as a 1 high range (row-like)
|
|
207
|
+
|
|
208
|
+
if True, one dimenional lists will be treated as a 1 wide range (column-like)
|
|
209
|
+
|
|
210
|
+
This parameter is not used for proper 2 dimensional list of lists
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
block
|
|
215
|
+
|
|
216
|
+
Note
|
|
217
|
+
----
|
|
218
|
+
number_of_rows and number_of_columns will be retrieved from list_of_lists dimension
|
|
219
|
+
"""
|
|
220
|
+
if not isinstance(list_of_lists, list):
|
|
221
|
+
list_of_lists = [[list_of_lists]]
|
|
222
|
+
if not isinstance(list_of_lists[0], list):
|
|
139
223
|
if column_like:
|
|
140
|
-
list_of_lists=[[value] for value in list_of_lists]
|
|
224
|
+
list_of_lists = [[value] for value in list_of_lists]
|
|
141
225
|
else:
|
|
142
|
-
list_of_lists=[list_of_lists]
|
|
226
|
+
list_of_lists = [list_of_lists]
|
|
143
227
|
|
|
144
|
-
self=cls(
|
|
228
|
+
self = cls(1, 1)
|
|
145
229
|
|
|
146
|
-
self.number_of_rows=len(list_of_lists)
|
|
147
|
-
self.
|
|
148
|
-
|
|
230
|
+
self.number_of_rows = len(list_of_lists)
|
|
231
|
+
self._number_of_columns = 0
|
|
149
232
|
|
|
150
|
-
for row,row_contents in enumerate(list_of_lists,1):
|
|
151
|
-
for column,value in enumerate(row_contents,1):
|
|
233
|
+
for row, row_contents in enumerate(list_of_lists, 1):
|
|
234
|
+
for column, value in enumerate(row_contents, 1):
|
|
152
235
|
if value is not None:
|
|
153
|
-
self.dict[row,column]=value
|
|
154
|
-
self.
|
|
236
|
+
self.dict[row, column] = value
|
|
237
|
+
self._number_of_columns = max(self.number_of_columns, column)
|
|
155
238
|
return self
|
|
156
|
-
|
|
239
|
+
|
|
157
240
|
def __setitem__(self, row_column, value):
|
|
158
|
-
row,column=row_column
|
|
159
|
-
if row<1 or row>self.number_of_rows:
|
|
241
|
+
row, column = row_column
|
|
242
|
+
if row < 1 or row > self.number_of_rows:
|
|
160
243
|
raise IndexError
|
|
161
|
-
if column<1 or column>self.number_of_columns:
|
|
244
|
+
if column < 1 or column > self.number_of_columns:
|
|
162
245
|
raise IndexError
|
|
163
|
-
|
|
164
|
-
del self.dict[row,column]
|
|
165
|
-
else:
|
|
166
|
-
self.dict[row,column]=value
|
|
246
|
+
self.dict[row, column] = value
|
|
167
247
|
|
|
168
248
|
def __getitem__(self, row_column):
|
|
169
|
-
row,column=row_column
|
|
170
|
-
if row<1 or row>self.number_of_rows:
|
|
249
|
+
row, column = row_column
|
|
250
|
+
if row < 1 or row > self.number_of_rows:
|
|
171
251
|
raise IndexError
|
|
172
|
-
if column<1 or column>self.number_of_columns:
|
|
252
|
+
if column < 1 or column > self.number_of_columns:
|
|
173
253
|
raise IndexError
|
|
174
|
-
return self.dict.get((row,column))
|
|
254
|
+
return self.dict.get((row, column))
|
|
175
255
|
|
|
176
256
|
@property
|
|
177
257
|
def as_list_of_lists(self):
|
|
178
|
-
return [[self.dict.get((row,column)) for column in range(1,self.number_of_columns+1)] for row in range(1,self.number_of_rows+1)]
|
|
179
|
-
|
|
258
|
+
return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def as_minimal_list_of_lists(self):
|
|
262
|
+
return [[self.dict.get((row, column)) for column in range(1, self.maximum_column + 1)] for row in range(1, self.maximum_row + 1)]
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def number_of_rows(self):
|
|
266
|
+
return self._number_of_rows
|
|
267
|
+
|
|
268
|
+
@number_of_rows.setter
|
|
269
|
+
def number_of_rows(self, value):
|
|
270
|
+
if value<1:
|
|
271
|
+
raise ValueError(f"number_of_rows should be >=1, not {value}")
|
|
272
|
+
self._number_of_rows = value
|
|
273
|
+
for row, column in list(self.dict):
|
|
274
|
+
if row > self._number_of_rows:
|
|
275
|
+
del self.dict[row, column]
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def number_of_columns(self):
|
|
279
|
+
return self._number_of_columns
|
|
280
|
+
|
|
281
|
+
@number_of_columns.setter
|
|
282
|
+
def number_of_columns(self, value):
|
|
283
|
+
if value<1:
|
|
284
|
+
raise ValueError(f"number_of_columns should be >=1, not {value}")
|
|
285
|
+
self._number_of_columns = value
|
|
286
|
+
for row, column in list(self.dict):
|
|
287
|
+
if column > self._number_of_columns:
|
|
288
|
+
del self.dict[row, column]
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def maximum_row(self):
|
|
292
|
+
if self.dict:
|
|
293
|
+
return max(row for (row, column) in self.dict)
|
|
294
|
+
else:
|
|
295
|
+
return 1
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def maximum_column(self):
|
|
299
|
+
if self.dict:
|
|
300
|
+
return max(column for (row, column) in self.dict)
|
|
301
|
+
else:
|
|
302
|
+
return 1
|
|
180
303
|
|
|
181
304
|
def __repr__(self):
|
|
182
305
|
return f"block.from_list_of_lists({self.as_list_of_lists})"
|
|
183
306
|
|
|
307
|
+
|
|
184
308
|
def clear_captured_stdout():
|
|
185
309
|
"""
|
|
186
310
|
empties the captured stdout
|
|
@@ -201,9 +325,9 @@ def captured_stdout_as_str():
|
|
|
201
325
|
return "".join(_captured_stdout)
|
|
202
326
|
|
|
203
327
|
|
|
204
|
-
def
|
|
328
|
+
def captured_stdout_as_list_of_lists():
|
|
205
329
|
"""
|
|
206
|
-
returns the captured stdout as a list of
|
|
330
|
+
returns the captured stdout as a list of lists
|
|
207
331
|
|
|
208
332
|
Returns
|
|
209
333
|
-------
|
|
@@ -256,31 +380,3 @@ class capture_stdout:
|
|
|
256
380
|
|
|
257
381
|
if __name__ == "__main__":
|
|
258
382
|
...
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
# @xw.script
|
|
262
|
-
# def test_stdout(book: xw.Book):
|
|
263
|
-
# with capture_stdout():
|
|
264
|
-
# for i in range(10):
|
|
265
|
-
# print(10 * f'{i}')
|
|
266
|
-
# book.sheets.active.range("A1").value=captured_stdout_as_range()
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
# @xw.script
|
|
270
|
-
# def test(book: xw.Book):
|
|
271
|
-
# dropbox_init(
|
|
272
|
-
# refresh_token=REFRESH_TOKEN,
|
|
273
|
-
# app_key=APP_KEY,
|
|
274
|
-
# app_secret=APP_SECRET,
|
|
275
|
-
# )
|
|
276
|
-
|
|
277
|
-
# files =list_dropbox("/Downloads",recursive=True)
|
|
278
|
-
# peek(files)
|
|
279
|
-
# write_pyodide("Test/x.x", b"abc")
|
|
280
|
-
# files = list_pyodide("Test")
|
|
281
|
-
|
|
282
|
-
# # files=list_dropbox_files("/Downloads")
|
|
283
|
-
# # peek(files)
|
|
284
|
-
# contents = read_dropbox("/Downloads/dropbox setup.py")
|
|
285
|
-
# write_dropbox("/Downloads/dropbox setup1.py", contents)
|
|
286
|
-
# peek("done")
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
+
xlwings_utils/xlwings_utils.py,sha256=J2eMXggaLHXLyNnw5n3Am6bDrMxgdyZZxT24lhmhups,9494
|
|
3
|
+
xlwings_utils-0.0.4.dist-info/METADATA,sha256=H1En9zmkXwQaRbANKdz64auexCwoCN_BFeY0n-cm_yk,1662
|
|
4
|
+
xlwings_utils-0.0.4.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
|
|
5
|
+
xlwings_utils-0.0.4.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
+
xlwings_utils-0.0.4.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
-
xlwings_utils/xlwings_utils.py,sha256=M6CkB1x9LjXIthWTlCAtN6T7c9bIPXx4HWv6s36kW9w,7060
|
|
3
|
-
xlwings_utils-0.0.2.dist-info/METADATA,sha256=iX4B9PHh-RmwWFG9-EeQPQ8pkycj_I5VOxCLRGukG7I,1662
|
|
4
|
-
xlwings_utils-0.0.2.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
|
|
5
|
-
xlwings_utils-0.0.2.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
-
xlwings_utils-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|