Bypass exception to always execute command? - python

The following code works almost perfect, thanks to the help received here:
import urllib.request
import zipfile
import subprocess
urls = ["http://url.com/archive1.zip", "http://url.com/archive2.zip", "http://url.com/archive3.zip"]
filename = "C:/test/test.zip"
destinationPath = "C:/test"
for url in urls:
try:
urllib.request.urlretrieve(url,filename)
sourceZip = zipfile.ZipFile(filename, 'r')
break
except ValueError:
pass
for name in sourceZip.namelist():
sourceZip.extract(name, destinationPath)
sourceZip.close()
subprocess.call(r'C:\WINDOWS\system32\cmd.exe /C "C:\test\test.exe"')
Except that when none of the url's successfully download, the final subprocess.call command never gets executed and I get the following error:
Traceback (most recent call last):
File "test.py", line 29, in <module>
for name in sourceZip.namelist():
NameError: name 'sourceZip' is not defined
I have been playing around a bit with the try: and except, but can not come to a working solution. I believe it is because the try: except command has to be inside the sourceZip loop, but since the sourceZip variable never gets declared, it fails. How would I alter this code to have the subprocess.call always get executed at the end regardless whether the download is successfull or not? (very new to Python)

Set sourceZip = None prior to the for url in urls line. Then test if sourceZip is None after the for loop to determine if you were able to successfully fetch the file. For example:
sourceZip = None
for url in urls:
try:
urllib.request.urlretrieve(url,filename)
sourceZip = zipfile.ZipFile(filename, 'r')
break
except ValueError:
pass
if sourceZip is not None:
for name in sourceZip.namelist():
sourceZip.extract(name, destinationPath)
sourceZip.close()
subprocess.call(r'C:\WINDOWS\system32\cmd.exe /C "C:\test\test.exe"')

Initialize sourceZip to None. Then check if it is not none do the extraction and closing.

Related

Is there a way to prevent the "bad connection" or "no network" error inside python?

I use urlopen command from urllib.request package and it works properly.
But because it is inside an infinite loop I want to consider the possible "No network" Conditions. I do not want my code to break down because of this error.
I tried the function below but it does not work:
def update():
try:
cmd = 'getUpdates'
resp = urlopen(URL + cmd)
line = aux_dec2utf8(resp)
upds = json.loads(line)
NoM = len(upds['result'])
except ValueError:
print('NO NETWORK')
return NoM, upds
Error Image
I think the issue here is the ValueError exception. You may want to set up an exception for urllib.HTTPError and/or urllib.URLError to catch the error you’re attempting to keep from breaking your script.
ValueError is used to catch an invalid argument and may not be what’s killing the flow.

Python - variable not defined but I think it is

I am pulling images from the Internet Archive as a test of some python code and I am incorporating the requests module. My code is as follows: (note, not the entire code, just the relevant section)
image_results = []
image_hashes = []
session = requests.Session()
for image in image_list:
if txtUrl not in image:
continue
try:
self.rslBox.AppendText("[v] Downloading %s" % image + "\n")
self.rslBox.Refresh()
response = session.get(image)
except:
self.rslBox.AppendText("[!] Failed to download: %s" % image + "\n")
self.rslBox.Refresh()
# continue
if "image" in response.headers['content-type']:
sha1 = hashlib.sha1(response.content).hexadigest()
if sha1 not in image_hashes:
image_hashes.append(sha1)
image_path = "WayBackImages/%s-%s" % (sha1.image.split("/")[-1])
with open(image_path, "wb") as fd:
fd.write(response.content)
self.rslBox.AppendText("[*] Saved %s" % images + "\n")
self.rslBox.Refresh()
info = pyexifinfo.get_json(image_path)
info[0]['ImageHash'] = sha1
image_results.append(info[0])
image_results_json = json.dumps(image_results)
data_frame = pandas.read_json(image_results_json)
csv = data_frame.to_csv('results.csv')
self.rslBox.AppendText("[*] Finished writing CSV to results.csv" + '\n')
self.rslBox.Refresh()
return
When I run my code, I get the following message:
Traceback (most recent call last):
File "C:\eclipse-workspace\test\tabbedPage.py", line 136, in OnSearch
if "image" in response.headers['content-type']:
NameError: name 'response' is not defined
But response is defined in the try statement - or so I would think. It only complains on the if "image" section - why??
I am new to python and I am using python3.6 and pydev with Eclipse.
Thanks!
Something inside your try failed. Your except caught it handle the error but since there is no raise in it, it continues execution, but response is not set.
It's because you are declaring response in the try block. If the exception gets thrown then response is not declared.
A work around for this would be putting the code that relies on response being declared into that try block.

Python else issues making an FTP program

I am having an issue with the else statement of this program... I have checked my spacing and it seems to be correct. I keep getting syntax error on the else statement. The program creates and file then attempts to upload it to a ftp server but if it fails to not say anything to the user and just continue It will try again when the program loops. Any help you could provide would be greatly appreciated.
#IMPORTS
import ConfigParser
import os
import random
import ftplib
from ftplib import FTP
#LOOP PART 1
from time import sleep
while True:
#READ THE CONFIG FILE SETUP.INI
config = ConfigParser.ConfigParser()
config.readfp(open(r'setup.ini'))
path = config.get('config', 'path')
name = config.get('config', 'name')
#CREATE THE KEYFILE
filepath = os.path.join((path), (name))
if not os.path.exists((path)):
os.makedirs((path))
file = open(filepath,'w')
file.write('text here')
file.close()
#Create Full Path
fullpath = path + name
#Random Sleep to Accomidate FTP Server
sleeptimer = random.randrange(1,30+1)
sleep((sleeptimer))
#Upload File to FTP Server
try:
host = '0.0.0.0'
port = 3700
ftp = FTP()
ftp.connect(host, port)
ftp.login('user', 'pass')
file = open(fullpath, "rb")
ftp.cwd('/')
ftp.storbinary('STOR ' + name, file)
ftp.quit()
file.close()
else:
print 'Something is Wrong'
#LOOP PART 2
sleep(180.00)
else is valid as part of an exception block, but it is only run if an exception is not raised and there must be a except defined before it.
(edit) Most people skip the else clause and just write code after exiting (dedenting) from the try/except clauses.
The quick tutorial is:
try:
# some statements that are executed until an exception is raised
...
except SomeExceptionType, e:
# if some type of exception is raised
...
except SomeOtherExceptionType, e:
# if another type of exception is raised
...
except Exception, e:
# if *any* exception is raised - but this is usually evil because it hides
# programming errors as well as the errors you want to handle. You can get
# a feel for what went wrong with:
traceback.print_exc()
...
else:
# if no exception is raised
...
finally:
# run regardless of whether exception was raised
...

Argument is URL or path

What is the standard practice in Python when I have a command-line application taking one argument which is
URL to a web page
or
path to a HTML file somewhere on disk
(only one)
is sufficient the code?
if "http://" in sys.argv[1]:
print "URL"
else:
print "path to file"
import urlparse
def is_url(url):
return urlparse.urlparse(url).scheme != ""
is_url(sys.argv[1])
Depends on what the program must do. If it just prints whether it got a URL, sys.argv[1].startswith('http://') might do. If you must actually use the URL for something useful, do
from urllib2 import urlopen
try:
f = urlopen(sys.argv[1])
except ValueError: # invalid URL
f = open(sys.argv[1])
Larsmans might work, but it doesn't check whether the user actually specified an argument or not.
import urllib
import sys
try:
arg = sys.argv[1]
except IndexError:
print "Usage: "+sys.argv[0]+" file/URL"
sys.exit(1)
try:
site = urllib.urlopen(arg)
except ValueError:
file = open(arg)

First Python Program - Multiple Errors

I am trying to write a python program that will eventually take a command line argument of a file, determine if its a tar or zip etc file and then exctract it accordingly. I am just trying to get the tar part working now and I am getting multiple errors. The file I am checking for resides in my ~/ directory. Any ideas would be great.
#!/usr/bin/python
import tarfile
import os
def open_tar(file):
if tarfile.is_tarfile(file):
try:
tar = tarfile.open("file")
tar.extractall()
tar.close()
except ReadError:
print "File is somehow invalid or can not be handled by tarfile"
except CompressionError:
print "Compression method is not supported or data cannot be decoded"
except StreamError:
print "Is raised for the limitations that are typical for stream-like TarFile objects."
except ExtractError:
print "Is raised for non-fatal errors when using TarFile.extract(), but only if TarFile.errorlevel== 2."
if __name__ == '__main__':
file = "xampp-linux-1.7.3a.tar.gz"
print os.getcwd()
print file
open_tar(file)
Here are the errors. IF I comment out the Read Error, I just get teh same error on the next exception as well.
tux#crosnet:~$ python openall.py
/home/tux
xampp-linux-1.7.3a.tar.gz
Traceback (most recent call last):
File "openall.py", line 25, in <module>
open_tar(file)
File "openall.py", line 12, in open_tar
except ReadError:
NameError: global name 'ReadError' is not defined
tux#crosnet:~$
You can clearly see in your error it states
NameError: global name 'ReadError' is not defined
ReadError is not a global python name. If you look at the tarfile documentation you will see ReadError is part of that modules exceptions. So in this case, you would want to do:
except tarfile.ReadError:
# rest of your code
And you will need to do the same for the rest of those errors. Also, if all those errors will generate the same result (an error message of some sort, or a pass) you can simply do:
except (tarfile.ReadError, tarfile.StreamError) # and so on
Instead of doing them each on a seperate line. That's only if they will give the same exception
You would need to use except tarfile.ReadError or alternatively use from tarfile import is_tarfile, open, ReadError, CompressionError, etc. and put that inside the open_tar function instead of globally.
I think you might need tarfile.ReadError rather than just ReadError?
Okay. All your exceptions (ReadError, CompressionError etc.) are inside the tarfile module and so you'll have to say except tarfile.ReadError instead of just except ReadError.

Categories

Resources