xlwings-utils 25.0.5.post0__py3-none-any.whl → 25.0.6__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.

@@ -5,7 +5,7 @@
5
5
  # /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
6
6
  # |___/ |_____|
7
7
 
8
- __version__ = "25.0.5"
8
+ __version__ = "25.0.6"
9
9
 
10
10
 
11
11
  import dropbox
@@ -155,7 +155,7 @@ def list_dropbox(path="", recursive=False, show_files=True, show_folders=False):
155
155
  return out
156
156
 
157
157
 
158
- def read_dropbox(dropbox_path):
158
+ def read_dropbox(dropbox_path, max_retries=100):
159
159
  """
160
160
  read_dropbox
161
161
 
@@ -166,6 +166,9 @@ def read_dropbox(dropbox_path):
166
166
  dropbox_path : str or Pathlib.Path
167
167
  path to read from
168
168
 
169
+ max_retries : int
170
+ number of retries (default: 100)
171
+
169
172
  Returns
170
173
  -------
171
174
  contents of the dropbox file : bytes
@@ -175,16 +178,17 @@ def read_dropbox(dropbox_path):
175
178
  If REFRESH_TOKEN, APP_KEY and APP_SECRET environment variables are specified,
176
179
  it is not necessary to call dropbox_init() prior to any dropbox function.
177
180
 
178
- If the file size does not match the metadata, as sometimes happens on pyodide, an OSError exception will be raised.
181
+ As reading from dropbox is very unreliable under pyodide, reading will have to be retried (by default maximum 100 times).
182
+ The number of retries can be found with read_dropbox.retries
179
183
  """
180
184
 
181
185
  _login_dbx()
182
- metadata, response = dbx.files_download(dropbox_path)
183
- file_content = response.content
184
- if len(file_content) != metadata.size:
185
- raise OSError(f"file size ({len(file_content)}) does not match metadata ({metadata.size})")
186
- return file_content
187
-
186
+ for read_dropbox.retries in range(max_retries+1):
187
+ metadata, response = dbx.files_download(dropbox_path)
188
+ file_content = response.content
189
+ if len(file_content) == metadata.size:
190
+ return file_content
191
+ raise OSError(f"after {max_retries} still no valid response")
188
192
 
189
193
  def write_dropbox(dropbox_path, contents):
190
194
  _login_dbx()
@@ -680,29 +684,26 @@ class block:
680
684
  return self.vlookup(s, row_from=row_from, row_to=row_to, column1=column1, column2=column2, default=default)
681
685
 
682
686
  def decode_to_files(self):
683
- """
687
+ """
684
688
  decode the block with encoded file(s) to individual local files
685
689
  """
690
+ for column in self.number_of_columns:
691
+ row = 1
692
+ while row <= self.number_of_rows:
693
+ if self[row, column] and self[row, column].startswith("<file=") and self[row, column].endswith(">"):
694
+ filename = self[row, column][6:-1]
695
+ collect = []
696
+ row += 1
697
+ while self[row, column] != "</file>":
698
+ print(f"{self[row,column]=}")
699
+
700
+ if self[row, column]:
701
+ collect.append(self[row, column])
702
+ row += 1
703
+ decoded = base64.b64decode("".join(collect))
704
+ open(filename, "wb").write(decoded)
705
+ row += 1
686
706
 
687
- row=1
688
- while row<=self.number_of_rows:
689
- if self[row,1] and self[row,1].startswith('<file=') and self[row,1].endswith('>'):
690
- filename=self[row,1][6:-1]
691
- collect=[]
692
- row+=1
693
- print(f"{filename=}")
694
-
695
- while self[row,1]!='</file>':
696
- print(f"{self[row,1]=}")
697
-
698
- if self[row,1]:
699
- collect.append(self[row,1])
700
- row+=1
701
- print(f"{collect=}")
702
- decoded=base64.b64decode(''.join(collect))
703
- open(filename,'wb').write(decoded)
704
- row+=1
705
-
706
707
  @classmethod
707
708
  def encode_files(cls, *files):
708
709
  """
@@ -711,7 +712,7 @@ class block:
711
712
  Parameters
712
713
  ----------
713
714
  files : file names (str)
714
- files to be encoded
715
+ files to be encoded
715
716
 
716
717
  Returns
717
718
  -------
@@ -719,8 +720,8 @@ class block:
719
720
  not minimized!
720
721
  """
721
722
 
722
- bl =cls(number_of_rows=50000, number_of_columns=1)
723
-
723
+ bl = cls(number_of_rows=50000, number_of_columns=1)
724
+
724
725
  n = 5000 # block size
725
726
  row = 1
726
727
  for file in files:
@@ -733,10 +734,10 @@ class block:
733
734
  row += 1
734
735
  b64 = b64[n:]
735
736
  bl[row, 1] = f"</file>"
736
- row+=1
737
+ row += 1
737
738
  return bl
738
-
739
-
739
+
740
+
740
741
  class Capture:
741
742
  """
742
743
  specifies how to capture stdout
@@ -842,9 +843,8 @@ class Capture:
842
843
  @include_print.setter
843
844
  def include_print(self, value):
844
845
  self._include_print = value
845
-
846
846
 
847
- def trigger(sheet):
847
+ def trigger_macro(sheet):
848
848
  """
849
849
  triggers the macro on sheet
850
850
 
@@ -852,11 +852,12 @@ def trigger(sheet):
852
852
  ----------
853
853
  sheet : sheet
854
854
  sheet to use
855
-
855
+
856
856
  """
857
857
 
858
858
  sheet["A1"].value = "=NOW()"
859
859
 
860
-
860
+
861
861
  if __name__ == "__main__":
862
862
  ...
863
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlwings_utils
3
- Version: 25.0.5.post0
3
+ Version: 25.0.6
4
4
  Summary: xlwings_utils
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/salabim/xlwings_utils
@@ -62,8 +62,7 @@ python -c "exec(__import__('requests').get('https://salabim.org/dropbox setup.py
62
62
  Then, it is possible to list all files in a specified folder using the list_dropbox function.
63
63
  It is also possible to get the folders and to access all underlying folders.
64
64
 
65
- The `read_dropbox` function can be used to read the contents (bytes) of a Dropbox file. If the file is not read correctly, which seems
66
- to happen rather frequently, an OSError exception is raised.
65
+ The `read_dropbox` function can be used to read the contents (bytes) of a Dropbox file. As reading from Dropbox under pyodide is very unreliable, xlwings_utils automatically retries several times (by default 100 times). The actual number of retries can be found with `read_dropbox.retries`.
67
66
 
68
67
  The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
69
68
 
@@ -267,31 +266,34 @@ Clearing the captured stdout buffer can be done at any time with `capture.clear(
267
266
 
268
267
  Currently, *xlwings Lite* does not provide access to the local file system. Therefore, xlwings_utils offers some functionality to trigger a VBA script as well as functionality to encode a file in the pyodide file system to a VBA sheet and to trigger writing the encoded file(s) to the local file system.
269
268
 
270
- Note that the sheet must have a worksheet named `VBA`, and the VBA code will normally reside there.
269
+ Files can be encoded into a block, like:
271
270
 
272
- There are three Python functions defined:
271
+ ```
272
+ bl = xwu.block.encode_files("film1.mp4", "settings.txt")
273
+ book.sheets["VBA"].range((10,2)).value=bl.value
274
+ ```
273
275
 
274
- * `trigger_VBA()`
275
- fires a VBA script, provided a VBA function is defined on the sheet, like:
276
-
277
- ```
278
- Sub Worksheet_Calculate()
279
- If Me.Range("A1").Formula = "=NOW()" Then
280
- Me.Range("A1").Value = Null
281
- REM Code to run
282
- End If
283
- End Sub
284
- ```
285
- * `init_transfer_files()`
286
- This should be called prior to any `transfer_file` call. It just removes all encoded files from the VBA sheet (if any)
276
+ With this code, column B will be filled with encoded copies of the files *film1.mp4* and *settings.txt* . This can then be used with a suitable VBA macro to decode to the real file system. A VBA macro can be triggered with `xwu.trigger_macro()`. This requires an Excel worksheet where cell A1 is reserved for communication with xlwings lite. This worksheet needs to contain a macro, like
277
+
278
+ ```
279
+ Private Sub Worksheet_Calculate()
280
+ If Me.Range("A1").Formula = "=NOW()" Then
281
+ Me.Range("A1").Value = Null
282
+ Call MacroToExecute
283
+ End If
284
+ End Sub
285
+ ```
286
+
287
+ , where `MacroToExecute` should contain the user code, most likely code to decode files encoded with something like
287
288
 
288
- * `transfer_file()`
289
- Can be used to encode a file on the pyodide file system to the VBA sheet. Multiple files are allowed. The file name will be encoded on the sheet as well.
289
+ ```
290
+ bl.decode_to_files()
291
+ ```
290
292
 
291
- The VBA code below can be used to decode encoded file(s) and write to the local file system.
293
+ The VBA code below can be used to decode encoded file(s ) on a worksheet.
292
294
 
293
295
  ```
294
- Sub WriteFiles()
296
+ Sub DecodeFiles()
295
297
 
296
298
  Dim vArr() As Byte
297
299
  Dim S As String
@@ -301,7 +303,7 @@ Sub WriteFiles()
301
303
  Dim Count As Integer
302
304
  Dim FileNames As String
303
305
 
304
- Column = 1
306
+ Column = 2
305
307
  Row = 1
306
308
 
307
309
  ThisDir = ThisWorkbook.Path
@@ -336,14 +338,11 @@ Sub WriteFiles()
336
338
  Row = Row + 1
337
339
 
338
340
  Wend
339
- If Cells(4, 2) = "y" Then
340
- ws.Range("A10:A1000000").Clear
341
- End If
342
341
 
343
342
  If Count = 0 Then
344
- MsgBox "No files written"
343
+ MsgBox "No files to decode"
345
344
  Else
346
- MsgBox "Successfully written " & Str(Count) & " file(s): " & FileNames
345
+ MsgBox "Successfully decoded and written " & Str(Count) & " file(s): " & FileNames
347
346
  End If
348
347
  ```
349
348
 
@@ -0,0 +1,6 @@
1
+ xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
+ xlwings_utils/xlwings_utils.py,sha256=5glVg37dkRfHSBT-gcSK-aKqAl-prDmRYcVh-Im0wt4,25463
3
+ xlwings_utils-25.0.6.dist-info/METADATA,sha256=aK8ufY5s5Wp7x1iU11g2dRNGaWRXOx67VAsM0wJJV6I,13139
4
+ xlwings_utils-25.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ xlwings_utils-25.0.6.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
+ xlwings_utils-25.0.6.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
- xlwings_utils/xlwings_utils.py,sha256=KP4RPmEyajLF2pn9IS3QEQyYC_xBn1yNoWzdh3cqqSo,25238
3
- xlwings_utils-25.0.5.post0.dist-info/METADATA,sha256=1amSYUkgWF76__slfIRyOpR-J-VbHjeoqmZxipWK21Q,13036
4
- xlwings_utils-25.0.5.post0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- xlwings_utils-25.0.5.post0.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
- xlwings_utils-25.0.5.post0.dist-info/RECORD,,