3

Based on the appium doc at http://appium.io/docs/en/commands/device/files/pull-folder/ a folder can be pulled following way

folder_base64 = self.driver.pull_folder('/path/to/device/foo.bar')

As per the doc the response folder_base64 is : "A string of Base64 encoded data, representing a zip archive of the contents of the requested folder."

So, based on my understanding of the above, i tried followings(A to D) which did not work.

A)

  1. base64 decoding of the folder_base64
  2. Unzipping the decoded output

decoded_base64 = base64.b64decode(folder_base64)

folder_base64 = ZipFile.extractall(decoded_base64)

this fails with following error:

zipfile.py", line 1493, in extractall
AttributeError: 'bytes' object has no attribute 'namelist'

B)

  1. base64 decoding of the folder_base64
  2. zipping the decoded output
  3. unzipping

decoded_base64 = base64.b64decode(folder_base64) zipfile.ZipFile('out.zip', mode='w').write(decoded_base64)

fails with following error at step 2:

zipfile.py", line 484, in from_file
    st = os.stat(filename)
ValueError: stat: embedded null character in path

C)

  1. unzipping the folder_base64
  2. base64 decoding of the output

unzipped_base64 = ZipFile.extractall(folder_base64) decoded_base64 = base64.b64decode(unzipped_base64)

fails at step 1 with following error

zipfile.py", line 1493, in extractall
AttributeError: 'str' object has no attribute 'namelist'

D)

  1. base64 decoding of the folder_base64
  2. read the file as zip file
  3. extract the files

decoded_base64 = base64.b64decode(folder_base64) zip_folder = zipfile.ZipFile(decoded_base64, 'r') ZipFile.extractall(zip_folder, "./mp3_files")

fails with following error:

zipfile.py", line 241, in _EndRecData
    fpin.seek(0, 2)
AttributeError: 'bytes' object has no attribute 'seek'

E)

Finally following worked, but i am wondering why it had to be routed via a temp file to make it work? Also, is there a better way/more direct way to handle appium pull_folder output?

decoded_base64 = base64.b64decode(folder_base64)
with SpooledTemporaryFile() as tmp:
    tmp.write(decoded_base64)
    archive = ZipFile(tmp, 'r')
    ZipFile.extractall(archive, "./mp3_files")

Note: following python packages are used in above code snippets

import zipfile
from tempfile import SpooledTemporaryFile
Nafeez Quraishi
  • 5,380
  • 2
  • 27
  • 34

1 Answers1

0

Also got error "SpooledTemporaryFile object has no attribute 'seekable'" from your solution E.

But this works for me:

folder_base64 = self.driver.pull_folder('/path/to/device/foo.bar')
decoded_base64 = base64.b64decode(folder_base64)

# write decoded content into a new file
with open("./archive.zip", "wb") as archive_file:
    archive_file.write(decoded_base64)

# extract created archive
with ZipFile('./archive.zip', 'r') as archive_file:        
    archive_file.extractall("./extracted_files")

# remove original file so only extracted files remain
os.remove("./archive.zip")
Karlo5o
  • 1
  • 1