Having an issue trying to download a encrypted/compressed 7zip file. I see the binary data being returned but still getting an error that the file is not downloaded. The information is being grabbed from a slack api by the 'url_private' property. The authentication is good, I see the byte data in my logger but still having issues.
import requests
import py7zr
url= "https://someurl/test_file.7z"
headers = {"auth": "token"}
response = requests.request("GET", url=file_url, headers=headers)
file_name = file_url.split("/")[-1]
if response.status_code == 200:
with py7zr.SevenZipFile(file_name, mode='r', password=pw) as file:
file.extractall(f"templates/files/")
# logger.debug(file_data)
file.close()
Error:
Failed to run listener function (error: [Errno 2] No such file or directory: 'test_file.7z')
Traceback (most recent call last):
File "/opt/venv/lib/python3.8/site-packages/slack_bolt/listener/thread_runner.py", line 103, in run_ack_function_asynchronously
listener.run_ack_function(request=request, response=response)
File "/opt/venv/lib/python3.8/site-packages/slack_bolt/listener/custom_listener.py", line 49, in run_ack_function
return self.ack_function(
File "/app/app/routes/events.py", line 62, in handle_file_shared
file = get_file_shared(file_url)
File "/app/app/lib/file_shared.py", line 28, in get_file_shared
with py7zr.SevenZipFile(file_name, mode='r', password=pw) as file:
File "/opt/venv/lib/python3.8/site-packages/py7zr/py7zr.py", line 324, in __init__
self.fp = open(file, "rb")
FileNotFoundError: [Errno 2] No such file or directory: 'test_file.7z'
I can't seem to find a solution, any help is appreciated.
You had most of it right. One of your problems might be that you didn't import the packages like requests. I found it by a simple google search.
import os
import requests
import py7zr
URL = "https://dl-alt1.winworldpc.com/Microsoft%20Windows%201.01%20Demo%20Slideshow%20(5.25).7z"
filename = os.path.basename(URL)
response = requests.get(URL, stream=True)
if response.status_code == 200:
with open(filename, 'wb') as out:
out.write(response.content)
with py7zr.SevenZipFile(filename, 'r') as archive:
archive.extractall(f"templates/files/")
else:
print('Request failed: %d' % response.status_code)
Related
question: How can I get this to work
I'm trying to use the python requests api to send a zipped file to a server. I saw this method in the docs:
r = requests.post(url, files=open('foo.png', 'rb'))
but the difference between what I'm doing, is that the zipped file that I have is in memory, there's just a python object, no physical zipped version of the file is created:
I'm using the zipfile api, and this is how I'm creating my zip file:
inMemoryOutputFile = StringIO()
outFile = zipfile.ZipFile(inMemoryOutputFile, "w",
compression=zipfile.ZIP_DEFLATED)
and trying the following (after writing to the zip file):
r = requests.post(url, outFile)
however its not working, looks like the object is not being recognized as a parameter. here's the stack trace
Traceback (most recent call last): File
"/Users/abdulahmad/Desktop/upload-script-ve/bin/cogs", line 11, in
<module>
sys.exit(main()) File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/cogs/run.py",
line 396, in main
return run(sys.argv) File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/cogs/run.py",
line 384, in run
return instance() File "/Users/abdulahmad/Desktop/upload-script-ve//src/ctl.py",
line 53, in __call__
handler = uploader(self.url, self.file) File "/Users/abdulahmad/Desktop/upload-script-ve//src/uploader.py",
line 24, in __call__
response = self.session.post(url, files=payload)
#this is where I'm adding the file (the payload)
File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/sessions.py",
line 511, in post
return self.request('POST', url, data=data, json=json, **kwargs) File
"/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/sessions.py",
line 454, in request
prep = self.prepare_request(req) File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/sessions.py",
line 388, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks), File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/models.py",
line 296, in prepare
self.prepare_body(data, files, json) File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/models.py",
line 447, in prepare_body
(body, content_type) = self._encode_files(files, data) File "/Users/abdulahmad/Desktop/upload-script-ve/lib/python2.7/site-packages/requests/models.py",
line 150, in _encode_files
fdata = fp.read() TypeError: read() takes at least 2 arguments (1 given)
actual code:
inMemoryOutputFile = StringIO()
parentDir, dirToZip = os.path.split(dirPath)
def trimPath(path):
archivePath = path.replace(parentDir, "", 1)
if parentDir:
archivePath = archivePath.replace(os.path.sep, "", 1)
if not includeDirInZip:
archivePath = archivePath.replace(dirToZip + os.path.sep, "", 1)
return os.path.normcase(archivePath)
outFile = zipfile.ZipFile(inMemoryOutputFile, "w",
compression=zipfile.ZIP_DEFLATED)
for (archiveDirPath, dirNames, fileNames) in os.walk(dirPath):
for fileName in fileNames:
filePath = os.path.join(archiveDirPath, fileName)
outFile.write(filePath, trimPath(filePath))
if not fileNames and not dirNames:
zipInfo = zipfile.ZipInfo(trimPath(archiveDirPath) + "/")
outFile.writestr(zipInfo, "")
outFile.close()
return outFile
You need to pass the StringIO buffer to requests, not the ZipFile. ZipFile.read("somefile.txt") reads an uncompressed file from the archive, it doesn't read the compressed binary stream. That read requires 1 parameter and that's why you got the strange error message. Rewind the file before posting or the POST data will be empty.
This example shows you the workflow.
import zipfile
from cStringIO import StringIO
import requests
import logging
logging.basicConfig(level=logging.DEBUG)
buf = StringIO()
with zipfile.ZipFile(buf, "w", compression=zipfile.ZIP_DEFLATED) as zippy:
zippy.write('somefile.txt')
buf.seek(0)
requests.post('http://localhost:8080',
headers = {'content-type': 'application/octet-stream'},
data=buf)
I used this code to scan multiple PDF files contained in a folder with the online scanner "https://wepawet.iseclab.org/" using this scrip.
import mechanize
import re
import os
def upload_file(uploaded_file):
url = "https://wepawet.iseclab.org/"
br = mechanize.Browser()
br.set_handle_robots(False) # ignore robots
br.open(url)
br.select_form(nr=0)
f = os.path.join("200",uploaded_file)
br.form.add_file(open(f) ,'text/plain', f)
br.form.set_all_readonly(False)
res = br.submit()
content = res.read()
with open("200_clean.html", "a") as f:
f.write(content)
def main():
for file in os.listdir("200"):
upload_file(file)
if __name__ == '__main__':
main()
but after the execution of the code I got the following error:
Traceback (most recent call last):
File "test.py", line 56, in <module>
main()
File "test.py", line 50, in main
upload_file(file)
File "test.py", line 40, in upload_file
res = br.submit()
File "/home/suleiman/Desktop/mechanize/_mechanize.py", line 541, in submit
return self.open(self.click(*args, **kwds))
File "/home/suleiman/Desktop/mechanize/_mechanize.py", line 203, in open
return self._mech_open(url, data, timeout=timeout)
File "/home/suleiman/Desktop/mechanize/_mechanize.py", line 255, in _mech_open
raise response
mechanize._response.httperror_seek_wrapper: HTTP Error refresh: The HTTP server returned a redirect error that would lead to an infinite loop.
The last 30x error message was:
OK
could any one help me with this problem ?
I think the issue is the mime-type text/plain you set. For PDF, this should be application/pdf. Your code with this change worked for me when I uploaded a sample PDF.
Change the br.form.add_file call to look like this:
br.form.add_file(open(f), 'application/pdf', f)
I'm currently hosting a SimpleHTTPServer locally and have cd'd it into my server folder. I'm trying to use afplay to get it to play audio that is currently located in the server folder. This is my code:
import subprocess
import os
import urllib
import urllib2
urllib.urlretrieve('http://0.0.0.0:8000', r'Daybreak.mp3')
return_code = subprocess.call(["afplay", audio_file])
The file is located in the folder the server is currently hosting from and I am getting GET requests in Terminal. This is the error I get:
File "<stdin>", line 1, in <module>
File "<string>", line 11, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 94, in urlretrieve
return _urlopener.retrieve(url, filename, reporthook, data)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 244, in retrieve
tfp = open(filename, 'wb')
IOError: [Errno 13] Permission denied: 'Daybreak.mp3'
I'm not sure why permission is denied as I have got read and write access to the folder.
You might have got read and write access to the folder. But you are not specifying your access credentials in the python script. Python has no way of knowing that you are authorized.
You may want to use some authorization method, like HTTPPasswordMgrWithDefaultRealm().
serverUrl = "..."
ID = "..."
accessToken = "..."
p = urllib2.HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, serverUrl, ID, accessToken)
handler = urllib2.HTTPBasicAuthHandler(p)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
req = urllib2.urlretrieve()
I want to send my application/zip data to the server without pycurl or other libs. I am newbie with cURL. Firstly i succesfully sent text/xml data with this code
import urllib2
req = urllib2.Request("http://192.168.79.131/rest", headers = {"Content-type" : "text/xml" , "Accept" : "*/*"} , data = '<income><name>acme7</name></income>')
f = urllib2.urlopen(req)
But now i want to upload my ZIP file to the server. I tried this code:
import urllib2
zipPath = "c:/somedir/ways.zip"
zipData = open(zipPath, "rb")
req = urllib2.Request("http://192.168.79.131/rest", headers = {"Content-type" : "application/zip" , "Accept" : "*/*"} , data = zipData)
f = urllib2.urlopen(req)
I got these errors:
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
f = urllib2.urlopen(req)
File "C:\Python27\lib\urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "C:\Python27\lib\urllib2.py", line 386, in open
protocol = req.get_type()
File "C:\Python27\lib\urllib2.py", line 248, in get_type
**raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: /rest/income**
Have you considered using something like Requests? It handles a lot of the urllib2 stuff so you don't have to:
import requests
url = 'http://httpbin.org/post'
files = {'file': open('c:/somedir/ways.zip', 'rb')}
r = requests.post(url, files=files)
print r
Prints:
>>> <Response [200]>
I have been trying to script a code with python to grade the main directory of that ftp and archive it into a the local pc. I am not an amateur coder and python is fairly new to me.
What I am getting as an error right now is.
File "C:\Users\Ali\Desktop\ftp_archiving_script.py", line 24, in <module>
ftpDownload = ftp.retrbinary('RETR', filename)
Code:
from ftplib import FTP
import zipfile
import os
try:
import zlib
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
modes = { zipfile.ZIP_DEFLATED: "deflated",
zipfile.ZIP_STORED: "stored",
}
#print "Logging in..."
with FTP('xxx.xxx.xxx') as ftp: #hostname goes here
ftp.login('xxxx','xxxx') #user followed by pass
#print "changing to root directory"
ftp.mlsd('//')
#print "Accessing files"
filenames = []
#print filenames
ftp.retrlines('NLST', filenames.append)
try:
for filename in filenames:
ftpDownload = ftp.retrbinary('RETR', filename)
with ZipFile(os.path.join('C:\\','DC_archive.zip'), 'w') as myzip:
myzip.write(ftpDownload, compress_type=compression)
myzip.close()
finally:
#print "closing"
ftp.close()
ftp.quit()
Can anyone enlighten me on this problem.
Thank you,
Update
try:
for filename in filenames:
with io.StringIO() as fObject:
ftp.retrbinary('RETR %s' %filename, fObject.write)
with ZipFile(os.path.join('C:\\','DC_archive.zip'), 'w') as myzip:
myzip.write(fObject, compress_type=compression)
myzip.close()
updated Traceback for #fals... Also this is using your code below and not the one I have at the top.
Traceback (most recent call last):
File "C:\Users\Ali\Desktop\ftp_archive2.py", line 20, in <module>
ftpDownload = ftp.retrbinary('RETR ' + filename, f.write)
File "C:\Python33\lib\ftplib.py", line 424, in retrbinary
with self.transfercmd(cmd, rest) as conn:
File "C:\Python33\lib\ftplib.py", line 386, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "C:\Python33\lib\ftplib.py", line 352, in ntransfercmd
resp = self.sendcmd(cmd)
File "C:\Python33\lib\ftplib.py", line 259, in sendcmd
return self.getresp()
File "C:\Python33\lib\ftplib.py", line 233, in getresp
raise error_perm(resp)
ftplib.error_perm: 550 File not found
From the Python documentation for ftplib.retrbinary:
FTP.retrbinary(command, callback[, maxblocksize[, rest]])
Retrieve a file in binary transfer mode. command should be an
appropriate RETR command: 'RETR filename'. The callback function is
called for each block of data received, with a single string argument
giving the data block.
Nowhere does it indicate that it returns a file-like object or string.
Instead, you have to create your own callback to write to a file object.
with open('my-downloaded-file', 'wb') as f:
ftp.retrbinary('RETR %s' % filename, f.write)
Here, f.write is the callback which will receive data as it arrives from the socket. If you don't want to save the file to disk using open, you can use the StringIO module to simulate a file in memory.
Try following code:
import ftplib
from io import BytesIO
import os
import zipfile
REMOTE_HOST = 'xxx.xxx.xxx'
REMOTE_USER = '...'
REMOTE_PASS = '...'
REMOTE_DIR_PATH = '//'
LOCAL_ZIP_PATH = os.path.join(os.path.expanduser('~'), 'Desktop', 'DC_archive.zip')
ftp = ftplib.FTP(REMOTE_HOST)
try:
ftp.login(REMOTE_USER, REMOTE_PASS)
ftp.cwd(REMOTE_DIR_PATH)
filenames = ftp.nlst()
with zipfile.ZipFile(LOCAL_ZIP_PATH, 'w') as zf:
for filename in filenames:
with BytesIO() as f:
try:
ftpDownload = ftp.retrbinary('RETR ' + filename, f.write)
zf.writestr(filename, f.getvalue())
except ftplib.Error as e:
print('Skip {}: {}'.format(filename, e))
finally:
ftp.quit()