It could be I'm completely misunderstanding the getopt module
I am trying to parse [--magic-m] to my program, but it does not set the correct field.
Part of Encrypt Function
def encrypt(filename, text, magic):
if not magic is None:
hash = pbkdf2_sha256.encrypt(magic, rounds=10000, salt_size=16)
print pbkdf2_sha256.verify(magic, hash)
try:
d = load_image( filename )
except Exception,e:
print str(e)
Part of Load function
def load_image( filename ) :
img = Image.open( os.path.join(__location__, filename) )
img.load()
data = np.asarray( img, dtype="int32" )
return data
Main
if __name__ == "__main__":
if not len(sys.argv[1:]):
usage()
try:
opts,args = getopt.getopt(sys.argv[1:],"hedm:",["help", "encrypt", "decrypt", "magic="])
except getopt.GetoptError as err:
print str(err)
usage()
magic = None
for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-e","--encrypt"):
to_encrypt = True
elif o in ("-d","--decrypt"):
to_encrypt = False
elif o in ("-m", "--magic"):
magic = a
else:
assert False,"Unhandled Option"
print magic
if not to_encrypt:
filename = sys.argv[2]
decrypt(filename, magic)
else:
filename = sys.argv[2]
text = sys.argv[3]
encrypt(filename, text, magic)
I tried calling the program above like this:
[1] python stego.py -e test.jpeg lol -m h
or like this:
[2] python stego.py -e -m h test.jpeg lol
Output becomes:
[1] None
[2] lol
[2] True
[2] [Errno 2] No such file or directory: 'C:\\Users\\Educontract\\Steganography\\-m'
Whitout the option -m everything works fine
The colon should come after m to indicate that it requires an argument. You should also include an equals sign after the long option magic to indicate that it requires an argument.
getopt.getopt(sys.argv[1:],"hedm:",["help", "encrypt", "decrypt", "magic="])
You should put all your options before the arguments, as in your second example.
python stego.py -e -m h test.jpeg lol
If you print sys.argv, I think you'll find that sys.argv[2] and sys.argv[3] are not what you expect. I would fetch the arguments from args, rather than sys.argv.
filename = args[0]
text = args[1]
Note that you may find it easier to use the argparse library instead of getopt. It isn't as strict about requiring options before arguments.
Related
The Python script below has worked for me in converting multiple PDF documents to a single PDF when running on Python 2.7. I'm now trying to use it on 3.10 and am getting errors.
I believe I've conquered most of them, especially changing print to print( and disabling imports of CoreFoundation and Quartz.CoreGraphics.
It seems that the only remaining error is:
line 85, in main
writeContext = CGPDFContextCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
arg, len(arg), False), None, None) NameError: name
'CGPDFContextCreateWithURL' is not defined
If I declare CGPDFContextCreateWithURL as an empty global, the error shifts to CFURLCreateFromFileSystemRepresentation. Declare that and the error is kCFAllocatorDefault.
Here's how I'm trying to handle those.
global CGPDFContextCreateWithURL CGPDFContextCreateWithURL = ""
I don't understand that entire line so any help in making it right would be appreciated.
#
# join
# Joing pages from a a collection of PDF files into a single PDF file.
#
# join [--output <file>] [--shuffle] [--verbose]"
#
# Parameter:
#
# --shuffle
# Take a page from each PDF input file in turn before taking another from each file.
# If this option is not specified then all of the pages from a PDF file are appended
# to the output PDF file before the next input PDF file is processed.
#
# --verbose
# Write information about the doings of this tool to stderr.
#
import sys
import os
import getopt
import tempfile
import shutil
# from CoreFoundation import *
# from Quartz.CoreGraphics import *
global verbose
verbose = False
def createPDFDocumentWithPath(path):
if verbose:
print("Creating PDF document from file %s" % (path))
return CGPDFDocumentCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, path, len(path), False))
def writePageFromDoc(writeContext, doc, pageNum):
page = CGPDFDocumentGetPage(doc, pageNum)
if page:
mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)
if CGRectIsEmpty(mediaBox):
mediaBox = None
CGContextBeginPage(writeContext, mediaBox)
CGContextDrawPDFPage(writeContext, page)
CGContextEndPage(writeContext)
if verbose:
print("Copied page %d from %s" % (pageNum, doc))
def shufflePages(writeContext, docs, maxPages):
for pageNum in xrange(1, maxPages + 1):
for doc in docs:
writePageFromDoc(writeContext, doc, pageNum)
def append(writeContext, docs, maxPages):
for doc in docs:
for pageNum in xrange(1, maxPages + 1) :
writePageFromDoc(writeContext, doc, pageNum)
def main(argv):
global verbose
# The PDF context we will draw into to create a new PDF
writeContext = None
# If True then generate more verbose information
source = None
shuffle = False
# Parse the command line options
try:
options, args = getopt.getopt(argv, "o:sv", ["output=", "shuffle", "verbose"])
except getopt.GetoptError:
usage()
sys.exit(2)
for option, arg in options:
if option in ("-o", "--output") :
if verbose:
print("Setting %s as the destination." % (arg))
writeContext = CGPDFContextCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, arg, len(arg), False), None, None)
elif option in ("-s", "--shuffle") :
if verbose :
print("Shuffle pages to the output file.")
shuffle = True
elif option in ("-v", "--verbose") :
print("Verbose mode enabled.")
verbose = True
else :
print("Unknown argument: %s" % (option))
if writeContext:
# create PDFDocuments for all of the files.
docs = map(createPDFDocumentWithPath, args)
# find the maximum number of pages.
maxPages = 0
for doc in docs:
if CGPDFDocumentGetNumberOfPages(doc) > maxPages:
maxPages = CGPDFDocumentGetNumberOfPages(doc)
if shuffle:
shufflePages(writeContext, docs, maxPages)
else:
append(writeContext, docs, maxPages)
CGPDFContextClose(writeContext)
del writeContext
#CGContextRelease(writeContext)
def usage():
print("Usage: join [--output <file>] [--shuffle] [--verbose]")
if __name__ == "__main__":
main(sys.argv[1:])
I have this script to perform config-backups from juniper-devices based on input from Netbox. I would like to expand this script a little to fetch the firmware version from the juniper device and update our netbox using a custom field.
#!/usr/bin/python3
import sys,os,getopt
from getpass import getpass
from jnpr.junos import Device
import jnpr.junos.facts
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import *
from lxml import etree
from pprint import pprint
import pynetbox
import datetime
nb = pynetbox.api(url='https://netbox-test/', token='<censored>')
save_path = '/config-backups/'
def printProgress(logtype,hostname,message):
print("%s:%s:%s"%(logtype,hostname,message))
def GetConfig(my_hostname, my_username, my_password):
try:
printProgress("INFO",my_hostname,"Connecting to device")
dev=Device(host=my_hostname,user=my_username,password=my_password)
dev.open(auto_probe=10)
dev.timeout=10
printProgress("INFO",my_hostname,"Retrieving config")
config = dev.rpc.get_config(options={'database':'committed','format':'set'})
junos_version = dev.facts['version']
configbackup = (etree.tostring(config, encoding='unicode', pretty_print=True))
completefilename = os.path.join(save_path, my_hostname+".set.config")
outfile=open(completefilename, "w")
outfile.write(configbackup)
dev.close()
outfile.close()
return True,junos_version
except Exception as err:
printProgress("ERROR",my_hostname,"Encountered exception while backing up config")
printProgress("ERROR",my_hostname,str(err))
return False
def main(argv):
junos_password = ''
try:
opts, args = getopt.getopt(argv,"?u:p:",["username=","password"])
except getopt.GetoptError:
print ('configbackup_junos.py -u <username> [-p <junos admin password>]')
sys.exit(2)
for opt, arg in opts:
if opt == '-?':
print ('configbackup_junos.py -u <username> [-p <junos admin password>]')
sys.exit()
elif opt in ("-u", "--username"):
junos_username = arg
elif opt in ("-p", "--password"):
junos_password = arg
print ('Will attempt to backup junos devices documented in Netbox using username:', junos_username)
if len(junos_password) > 0:
print ('Junos Password set on commandline\n')
else:
print ('password not entered, will ask for it')
junos_password=getpass(prompt="\nPassword: ")
nb_devicelist = nb.dcim.devices.all()
for nb_device in nb_devicelist:
platform = str(nb_device.platform)
pri_ip = str(nb_device.primary_ip)
asset = nb_device.asset_tag
devstatus = str(nb_device.status)
backup_enabled = nb_device.custom_fields['backup_enable']
if nb_device.virtual_chassis:
vchassismaster = str(nb_device.virtual_chassis.master)
else:
vchassismaster = 'no_chassis'
if backup_enabled == 'Yes' and platform == 'Junos' and devstatus == 'Active' and pri_ip != 'None' and asset:
if vchassismaster == (nb_device.name) or vchassismaster == 'no_chassis':
if GetConfig(asset,junos_username,junos_password):
print ("Config Successfully backed up from device.",nb_device)
nb_device.custom_fields['backup_status'] = "OK"
timenow = datetime.datetime.now()
timestamp = timenow.strftime("%Y-%m-d %X")
nb_device.custom_fields['backup_timestamp'] = timestamp
nb_device.save()
print (junos_version)
else:
printProgress ("ERROR",nb_device,"Config backup failed! ")
nb_device.custom_fields['backup_status'] = "FAILED"
nb_device.save()
print("")
if len(sys.argv) == 1:
sys.exit()
if __name__ == "__main__":
main(sys.argv[1:])
My problem is how do I get the variable "junos_version" returned from the function GetConfig. As you can see I have tried using "return True,junos_version", but how do I grab it in the output of the function?
(I have read all the articles I could find about this and tried a number of suggestions, but nothing works.
I need to be able to input the "junos_version" into this command
nb_device.custom_fields['firmware_version'] = junos_version
Which I wouldd placee just before the nb_device.save
I suspect it is my sense of logic that fails here, I just cannot see the forest for trees.
if GetConfig(asset,junos_username,junos_password):
you can change this with :
with flag, junos_version=GetConfig(asset,junos_username,junos_password):
If you return multiple values from a function, consider them a tuple.
In your case you can get the second value in the following way:
cfg = GetConfig(...) // add your args
junos_version = cfg[1] // get the 2-nd returned value from a tuple.
First you have to have a stable return.
def GetConfig(my_hostname, my_username, my_password):
try:
...
return True,junos_version
except Exception as err:
...
return False
In here you can have a tuple (of boolean and version) or a bool (True or False) as return.
I would change it as:
def GetConfig(my_hostname, my_username, my_password):
try:
...
return True,junos_version
except Exception as err:
...
return False, None
since there is no junos_version in exception.
Now you change the code where you use it as:
def main(argv):
...
if GetConfig(asset,junos_username,junos_password):
...
to
def main(argv):
...
cfg, version = GetConfig(asset,junos_username,junos_password)
if cfg:
...
I'm new to python and having some issues with blocking. I have a script that I'm calling with options. I'm able to see the arguments come in, however, I have been unable to get the program to work correctly. In the code sample below, I'm trying to grab the arguments and then run the piece of code after the "#if ip address is not defined qpid-route will not work" comment. If I change the indentation after the comment, I get expected indentation or unexpected indentation errors.
The problem is that the way the code currently is it will run the elif opt in ("-i", "--ipaddress"): code and then will continue and run the code through to the bottom and then come back and run the -s loop code and then rerun the code to the bottom.
To fix this, I tried a break or continue command and all I get is indentation errors on this no matter which level I align it with. Can someone help me format this correctly such that I can pull the ipaddress and scac values that I'm grabbing from the arguments and then run the code after the "#if ip address is not defined qpid-route will not work" comment as a separate block.
import re
import os
import sys
import getopt
import pdb
ipaddress = ""
scac = ''
def main(argv):
#print argv
ipaddress = ""
scac = ''
pdb.set_trace()
try:
opts, args = getopt.getopt(argv,"hi:s:",["ipaddress=","scac="])
if not opts: # if no option given
print 'usage test.py -i <ipaddress> -s <scac>'
sys.exit(2)
except getopt.GetoptError:
print 'test.py -i <ipaddress> -s <scac>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'FedConnectStatus.py -i <iobipaddress> -s <scac>'
sys.exit() # it should be on level of if
elif opt in ("-i", "--ipaddress"):
ipaddress = arg
#break
#continue
elif opt in ("-s", "--scac"):
scac = arg
#if ip address is not defined qpid-route will not work
if not ipaddress:
print 'ip address needed'
else:
print(os.getcwd())
#If no scac is given grab every federated connection and report
if not scac:
# open file to read
f = file('qpid.txt', 'r')
nameList = []
statusList = []
#skip first 4 lines
for i in range(3): f.next() # skip first four lines
# iterate over the lines in the file
for line in f:
# split the line into a list of column values
columns = line.split(None, 5)
# clean any whitespace off the items
columns = [col.strip() for col in columns]
# ensure the column has at least one value before printing
if columns:
#print "Name", columns[0] # print the first column
#print "Status", columns[4] # print the last column
nameList.append(columns[0])
statusList.append(columns[4])
#print name
#print status
#else:
print nameList
print statusList
#if __name__ == "__main__":
main(sys.argv[1:])
This statement if not scac: on line 40 and below has indentation different to that of the rest of the code.
You'll see line 38 also doesn't match the indenting of the above if.
How can I compare the values of input parmeters with a file in such a way that the sequence of the lines in file are "respected". For example:
file sequence.txt has following enteries
aaa
bbb
ccc
ddd
and the input is coming like this (with comas):
./run.py -c migrate -s ddd,bbb
then output is like this:
bbb
ddd
Here is the script I have worked so far
#!/usr/bin/python
import sys
import getopt
import time
import os
def main(argv):
cmd = ''
schemas = ''
script_dir = os.path.dirname(__file__)
seq_file = "system/sequence.txt"
abs_file_path = os.path.join(script_dir, seq_file)
try:
opts, args = getopt.getopt(argv,"h:c:s",["cmd=","schemas="])
except getopt.GetoptError:
print './run.py -c=<command> -s=<schemas> '
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print './run.py -c=<command> -s=<schemas>'
sys.exit()
elif opt in ("-c", "--cmd"):
cmd = arg
elif opt in ("-s", "--schemas"):
schemas = arg
if cmd == "migrate" :
with open(abs_file_path) as z:
for line in z:
print line.rstrip('\n')
if __name__ == "__main__":
main(sys.argv[1:])
I know that I have to do comparisons at position print line.rstrip('\n') but I can't figure out how to do it. Any suggestions?
Also, how can I make -s switch mandatory if -c has "migrate" value?
Thanks in advance.
You need to check whether the current line of the sequence is specified with the -s flag. So you need to modify the schemas value, so that it is a list that contains all schemas and then you can check if the current line is equal to one of the schemas. As for your second question, I'm not familiar with getopt, but you could simply check whether schemas is not empty when -c is migrate and do the approriate error handling.
[...]
schemas = []
[...]
elif opt in ("-s", "--schemas"):
schemas = arg.split(',')
[...]
if cmd == 'migrate':
if not schemas: # list is empty
# do error handling
for line in z:
if line in schemas:
print line
I am trying to copy parameters passed into a python script to a file. Here is the parameters.
["0013","1","1","\"john.dow#gmail.com\"","1","P123-ND 10Q","10Q H??C"]
I understand that there is a buffer problem and I am getting bad data into my parameters. However, I do not have control over what is being passed in. I am trying to copy, starting at the 5th parameter, the parameters into a file.
f = open(in_file_name, 'w')
for x in range(5, len(arg_list)):
f.write(arg_list[x] + '\n')
f.close()
The result of the file is below:
P123-ND 10Q
10Q H??C
Here is what it should be:
P123-ND
10Q
How can I not include the bad data? What is happening to the spaces between the valid information and the bad information?
As requested, here is the full program:
#!/bin/python
class Argument_Indices:
PRINTER_INDEX = 0
AREA_INDEX = 1
LABEL_INDEX = 2
EMAIL_INDEX = 3
RUN_TYPE_INDEX = 4
import argparse
import json
import os
from subprocess import call
import sys
from time import strftime
def _handle_args():
''' Setup and run argpars '''
parser = argparse.ArgumentParser(description='Set environment variables for and to call Program')
parser.add_argument('time_to_run', default='NOW', choices=['NOW', 'EOP'], help='when to run the report')
parser.add_argument('arguments', nargs='+', help='the remaining command line arguments')
return parser.parse_args()
def _proces_program(arg_list):
time_stamp = strftime("%d_%b_%Y_%H_%M_%S")
printer = arg_list[Argument_Indices.PRINTER_INDEX]
area = arg_list[Argument_Indices.AREA_INDEX]
label = arg_list[Argument_Indices.LABEL_INDEX]
in_file_name = "/tmp/program{0}.inp".format(time_stamp)
os.environ['INPUT_FILE'] = in_file_name
f = open(in_file_name, 'w')
for x in range(5, len(arg_list)):
f.write(arg_list[x])
f.close()
call(['./Program.bin', printer, area, label])
os.remove(in_file_name)
def main():
''' Main Function '''
arg_list = None
args = _handle_args()
if len(args.arguments) < 1:
print('Missing name of input file')
return -1
with open(args.arguments[0]) as input_file:
arg_list = json.load(input_file)
_process_program(arg_list)
return 0
if __name__ == '__main__':
if main() != 0:
print('Program run failed')
sys.exit()
For your exact case (where you're getting duplicated parameters received with some spaces in between) this would work:
received_param_list = ["0013","1","1","\"john.dow#gmail.com\"","1","P123-ND 10Q","10Q H??C"]
arg_list = [i.split(" ")[0] for i in received_param_list]
last_param = received_param_list[-1].split()[-1]
if last_param != arg_list[-1]:
arg_list.append(last_param)
for x in range(5, len(arg_list)):
print (arg_list[x])
Although there might be another simpler way