Hi am new to python and tried to run below script and getting attribute error.
#!/usr/bin/python
import json
import sys
import argparse
try:
import requests
except ImportError:
print "Please install the python-requests module."
sys.exit(-1)
def get_json(location, devincuser, password):
# Performs a GET using the passed URL location
location += "?per_page=10000"
r = requests.get(location, auth=(devincuser, password),verify=False)
return r.json()
def main():
parser = argparse.ArgumentParser(description="Satellite Errata
Reporter")
# Arguments
parser.add_argument("-u", "--devincuser", type=str.lower, help="Username
to access Satellite", action="store", default='devincuser')
parser.add_argument("-p", "--password", type=str, help="Password to
access Satellite", action="store", default='password')
parser.add_argument("-n", "--localhost", type=str.lower, help="Satellite
server (default: localhost)", default='localhost')
parser.add_argument("-o", "--organization", type=str.lower, nargs="*",
help="Filter on this space-delimited list of organization(s)", default='')
parser.add_argument("-e", "--environment", type=str.lower, nargs="*",
help="Filter on this space-delimited list of lifecycle environments",
default='')
parser.add_argument("-c", "--collection", type=str.lower, nargs="*",
help="Filter on and group by this space-delimited list of host
collections", default='')
parser.add_argument("-t", "--type", type=str.lower, nargs="*",
help="Filter on this space-delimeted list of errata types (bugfix,
enhancement, and/or security)", default='')
parser.add_argument("-s", "--severity", type=str.lower, nargs="*",
help="Filter on this space-delimited list of severities (critical,
important, moderate, low)", default='')
args = parser.parse_args()
# Check username and password
if not (args.username and args.password):
print "No complete account information provided, exiting"
exit (-1)
# set up api url
sat_api = "http://%s/172.17.12.129/api/v2/" % args.server
katello_api = "http://%s/172.17.12.129/api/" % args.server
# set up initial stuff
prefix = "- "
systems_fetched = False
system_count = 0
system_errata_count = 0
# Loop through organizations and skip the ones we don't want
orgs = get_json(sat_api + "organizations/", args.username,
args.password)
for org in orgs['results']:
if args.organization and org['name'].lower not in args.organization:
continue
print "\nErrata for organization '%s':" % org['name']
if args.collection:
# Loop through the host collections, skip the one we don't want
collections = get_json(sat_api + "organizations/" + str(org['id']) +
"/host_collections/", args.username, args.password)
for collection in collections['results']:
if collection['name'].lower() not in args.collection:
continue
print "\n" + prefix + "Errata for Host Collection '%s':" %
collection['name']
prefix = " - "
# Get the systems in this host collection
systems = get_json(sat_api + "host_collections/" + str(collection['id'])
+ "/systems/", args.username, args.password)
systems_fetched = True
else:
# Get the systems in this Organization
systems = get_json(sat_api + "organizations/" + str(org['id']) +
"/systems/", args.username, args.password)
systems_fetched = True
if not systems_fetched:
continue
# loop through the systems fetched from the collection *or* the
organization
for system in systems['results']:
system_errata = get_json(sat_api + "systems/" + system['uuid'] +
"/errata", args.username, args.password)
first = True
# filter on lifecycle environment(s) (if specified)
environment = system['environment']['name'].lower()
if args.environment and environment not in args.environment:
continue
# Get all available Errata for System
for system_erratum in system_errata['results']:
# filter on type(s) (if specified)
type = system_erratum['type'].lower()
if args.type and type not in args.type:
continue
# filter on severity(s) (if specified)
if type == "security" and "security" in args.type and args.severity:
severity = system_erratum['title'].split(":")
[0].encode('ascii','ignore').lower()
if severity not in args.severity:
continue
# We have an erratum, print system if this is the first
if first:
system_count += 1
first = False
print "\n" + prefix + system['name'], "("+system['environment']
['name']+")\n"
# print the erratum id, type and title
print " " + prefix + "%s: %s: %s" %
(system_erratum['errata_id'],system_erratum['type'],system_erratum['title'])
# Count the errata we find
system_errata_count += 1
if not first:
print
# print statistics
if system_errata_count:
print "\nNumber of errata to apply: %s" % system_errata_count
print "Number of systems affected: %s" % system_count
else:
print "\nNo errata found for this selection"
print
if __name__ == "__main__":
main()
and getting blow error
Traceback (most recent call last):
File "./pyth.py", line 136, in
main()
File "./pyth.py", line 44, in main
if not (args.username and args.password):
AttributeError: 'Namespace' object has no attribute 'username'
You haven't defined a username argument in your ArgumentParser. You've defined something called devincuser, did you mean to use that instead?
Related
springerlink has changed its structure, and now the script doesn't work anymore. With it you should could download all chapters at once instead of all single chapters.
i installed the script and its dependencies with linux.
from here http://milianw.de/code-snippets/take-2-download-script-for-springerlinkcom-ebooks and here https://github.com/milianw/springer_download
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import getopt
import urllib
import re
import tempfile
import shutil
import subprocess
# Set some kind of User-Agent so we don't get blocked by SpringerLink
class SpringerURLopener(urllib.FancyURLopener):
version = "Mozilla 5.0"
def pdfcat(fileList, bookTitlePath):
if findInPath("pdftk") != False:
command = [findInPath("pdftk")]
command.extend(fileList)
command.extend(["cat", "output", bookTitlePath])
subprocess.Popen(command, shell=False).wait()
elif findInPath("stapler") != False:
command = [findInPath("stapler"), "cat"]
command.extend(fileList)
command.append(bookTitlePath)
subprocess.Popen(command, shell=False).wait()
else:
error("You have to install pdftk (http://www.accesspdf.com/pdftk/) or stapler (http://github.com/hellerbarde/stapler).")
# validate CLI arguments and start downloading
def main(argv):
if not findInPath("iconv"):
error("You have to install iconv.")
#Test if convert is installed
if os.system("convert --version > /dev/null 2>&1")!=0:
error("You have to install the packet ImageMagick in order to use convert")
try:
opts, args = getopt.getopt(argv, "hl:c:n", ["help", "link=", "content=", "no-merge"])
except getopt.GetoptError:
error("Could not parse command line arguments.")
link = ""
hash = ""
merge = True
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-c", "--content"):
if link != "":
usage()
error("-c and -l arguments are mutually exclusive")
hash = arg
elif opt in ("-l", "--link"):
if hash != "":
usage()
error("-c and -l arguments are mutually exclusive")
match = re.match("(https?://)?(www\.)?springer(link)?.(com|de)/(content|.*book)/(?P<hash>[a-z0-9\-]+)/?(\?[^/]*)?$", arg)
if not match:
usage()
error("Bad link given. See example link.")
hash = match.group("hash")
elif opt in ("-n", "--no-merge"):
merge = False
if hash == "":
usage()
error("Either a link or a hash must be given.")
if merge and not findInPath("pdftk") and not findInPath("stapler"):
error("You have to install pdftk (http://www.accesspdf.com/pdftk/) or stapler (http://github.com/hellerbarde/stapler).")
baseLink = "http://www.springerlink.com/content/" + hash + "/"
link = baseLink + "contents/"
chapters = list()
loader = SpringerURLopener();
curDir = os.getcwd()
bookTitle = ""
coverLink = ""
front_matter = False
while True:
# download page source
try:
print "fetching book information...\n\t%s" % link
page = loader.open(link,"MUD=MP").read()
except IOError, e:
error("Bad link given (%s)" % e)
if re.search(r'403 Forbidden', page):
error("Could not access page: 403 Forbidden error.")
if bookTitle == "":
match = re.search(r'<h1[^<]+class="title">(.+?)(?:<br/>\s*<span class="subtitle">(.+?)</span>\s*)?</h1>', page, re.S)
if not match or match.group(1).strip() == "":
error("Could not evaluate book title - bad link %s" % link)
else:
bookTitle = match.group(1).strip()
# remove tags, e.g. <sub>
bookTitle = re.sub(r'<[^>]*?>', '', bookTitle)
# subtitle
if match and match.group(2) and match.group(2).strip() != "":
bookTitle += " - " + match.group(2).strip()
# edition
#match = re.search(r'<td class="labelName">Edition</td><td class="labelValue">([^<]+)</td>', page)
#if match:
#bookTitle += " " + match.group(1).strip()
## year
#match = re.search(r'<td class="labelName">Copyright</td><td class="labelValue">([^<]+)</td>', page)
#if match:
#bookTitle += " " + match.group(1).strip()
## publisher
#match = re.search(r'<td class="labelName">Publisher</td><td class="labelValue">([^<]+)</td>', page)
#if match:
#bookTitle += " - " + match.group(1).strip()
# coverimage
match = re.search(r'<div class="coverImage" title="Cover Image" style="background-image: url\(/content/([^/]+)/cover-medium\.gif\)">', page)
if match:
coverLink = "http://www.springerlink.com/content/" + match.group(1) + "/cover-large.gif"
bookTitlePath = curDir + "/%s.pdf" % sanitizeFilename(bookTitle)
if bookTitlePath == "":
error("could not transliterate book title %s" % bookTitle)
if os.path.isfile(bookTitlePath):
error("%s already downloaded" % bookTitlePath)
print "\nNow Trying to download book '%s'\n" % bookTitle
#error("foo")
# get chapters
for match in re.finditer('href="([^"]+\.pdf)"', page):
chapterLink = match.group(1)
if chapterLink[:7] == "http://": # skip external links
continue
if re.search(r'front-matter.pdf', chapterLink):
if front_matter:
continue
else:
front_matter = True
if re.search(r'back-matter.pdf', chapterLink) and re.search(r'<a href="([^"#]+)"[^>]*>Next</a>', page):
continue
#skip backmatter if it is in list as second chapter - will be there at the end of the book also
if re.search(r'back-matter.pdf', chapterLink):
if len(chapters)<2:
continue
chapters.append(chapterLink)
# get next page
match = re.search(r'<a href="([^"#]+)"[^>]*>Next</a>', page)
if match:
link = "http://www.springerlink.com" + match.group(1).replace("&", "&")
else:
break
if len(chapters) == 0:
error("No chapters found - bad link?")
print "found %d chapters" % len(chapters)
# setup; set tempDir as working directory
tempDir = tempfile.mkdtemp()
os.chdir(tempDir)
i = 1
fileList = list()
for chapterLink in chapters:
if chapterLink[0] == "/":
chapterLink = "http://www.springerlink.com" + chapterLink
else:
chapterLink = baseLink + chapterLink
chapterLink = re.sub("/[^/]+/\.\.", "", chapterLink)
print "downloading chapter %d/%d" % (i, len(chapters))
localFile, mimeType = geturl(chapterLink, "%d.pdf" % i)
if mimeType.gettype() != "application/pdf":
os.chdir(curDir)
shutil.rmtree(tempDir)
error("downloaded chapter %s has invalid mime type %s - are you allowed to download %s?" % (chapterLink, mimeType.gettype(), bookTitle))
fileList.append(localFile)
i += 1
if coverLink != "":
print "downloading front cover from %s" % coverLink
localFile, mimeType = geturl(coverLink, "frontcover")
if os.system("convert %s %s.pdf" % (localFile, localFile)) == 0:
fileList.insert(0, localFile + ".pdf")
if merge:
print "merging chapters"
if len(fileList) == 1:
shutil.move(fileList[0], bookTitlePath)
else:
pdfcat(fileList, bookTitlePath)
# cleanup
os.chdir(curDir)
shutil.rmtree(tempDir)
print "book %s was successfully downloaded, it was saved to %s" % (bookTitle, bookTitlePath)
log("downloaded %s chapters (%.2fMiB) of %s\n" % (len(chapters), os.path.getsize(bookTitlePath)/2.0**20, bookTitle))
else: #HL: if merge=False
print "book %s was successfully downloaded, unmerged chapters can be found in %s" % (bookTitle, tempDir)
log("downloaded %s chapters of %s\n" % (len(chapters), bookTitle))
sys.exit()
# give a usage message
def usage():
print """Usage:
%s [OPTIONS]
Options:
-h, --help Display this usage message
-l LINK, --link=LINK defines the link of the book you intend to download
-c ISBN, --content=ISBN builds the link from a given ISBN (see below)
-n, --no-merge Only download the chapters but don't merge them into a single PDF.
You have to set exactly one of these options.
LINK:
The link to your the detail page of the ebook of your choice on SpringerLink.
It lists book metadata and has a possibly paginated list of the chapters of the book.
It has the form:
http://www.springerlink.com/content/ISBN/STUFF
Where: ISBN is a string consisting of lower-case, latin chars and numbers.
It alone identifies the book you intent do download.
STUFF is optional and looks like #section=... or similar. It will be stripped.
""" % os.path.basename(sys.argv[0])
# raise an error and quit
def error(msg=""):
if msg != "":
log("ERR: " + msg + "\n")
print "\nERROR: %s\n" % msg
sys.exit(2)
return None
# log to file
def log(msg=""):
logFile = open('springer_download.log', 'a')
logFile.write(msg)
logFile.close()
# based on http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
def findInPath(prog):
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, prog)
if os.path.exists(exe_file) and os.access(exe_file, os.X_OK):
return exe_file
return False
# based on http://mail.python.org/pipermail/python-list/2005-April/319818.html
def _reporthook(numblocks, blocksize, filesize, url=None):
#XXX Should handle possible filesize=-1.
try:
percent = min((numblocks*blocksize*100)/filesize, 100)
except:
percent = 100
if numblocks != 0:
sys.stdout.write("\b"*70)
sys.stdout.write("%-66s%3d%%" % (url, percent))
def geturl(url, dst):
downloader = SpringerURLopener()
if sys.stdout.isatty():
response = downloader.retrieve(url, dst,
lambda nb, bs, fs, url=url: _reporthook(nb,bs,fs,url), "MUD=MP")
sys.stdout.write("\n")
else:
response = downloader.retrieve(url, dst, None, "MUD=MP")
return response
def sanitizeFilename(filename):
p1 = subprocess.Popen(["echo", filename], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["iconv", "-f", "UTF-8", "-t" ,"ASCII//TRANSLIT"], stdin=p1.stdout, stdout=subprocess.PIPE)
return re.sub("\s+", "_", p2.communicate()[0].strip().replace("/", "-"))
# start program
if __name__ == "__main__":
main(sys.argv[1:])
# kate: indent-width 4; replace-tabs on;
excpected: it should downlaod the book
actual results: with command ./springer_download.py -c "978-3-662-54804-2" i get ERROR: Could not evaluate book title - bad link http://www.springerlink.com/content/978-3-662-54804-2/contents/
the test
python2 ./springer_download.py -c "978-3-662-54804-2"
does not work either
in the code above the error is in the context
match = re.search(r'<h2 class="MPReader_Profiles_SpringerLink_Content_PrimitiveHeadingControlName">([^<]+)</h2>', page)
if not match or match.group(1).strip() == "":
error("Could not evaluate book title - bad link?")
else:
bookTitle = match.group(1).strip()
print "\nThe book you are trying to download is called '%s'\n" % bookTitle
i would also be happy with alternatives like browser addons or the like. Using the example https://link.springer.com/book/10.1007/978-3-662-54805-9#toc
I have been trying to incorporate boto3 into my AWS workflow after using fabric for a little while. Just started learning Python so apologies in advance for some of these questions. I searched and debugged what I could with the below script as most of the errors seemed prior seemed to be with this being written in Python2 and I am using Python3 on OSX. Sorry for the formatting issues as well tried to get the script into a code block for here.
#!/usr/bin/env python
import boto3
import sys
import argparse
import paramiko
def list_instances(Filter):
ec2 = boto3.resource('ec2')
instances = ec2.instances.filter(Filters=Filter)
columns_format = ("%-3s %-26s %-16s %-16s %-20s %-12s %-12s %-16s")
print (columns_format) ("num", "Name", "Public IP", "Private IP", "ID",
"Type", "VPC", "Status")
num = 1
hosts = []
name = {}
for i in instances:
try:
name = (item for item in i.tags if item["Key"] == "Name" ).next()
except StopIteration:
name['Value'] = ''
print (columns_format) % (
num,
name['Value'],
i.public_ip_address,
i.private_ip_address,
i.id,
i.instance_type,
i.vpc_id,
i.state['Name']
)
num = num + 1
item={'id': i.id, 'ip': i.public_ip_address, 'hostname':
name['Value'], 'status': i.state['Name'],}
hosts.append(item)
return hosts
def execute_cmd(host,user,cmd):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(host, username=user)
stdin, stdout, stderr = ssh.exec_command(cmd)
stdout=stdout.read()
stderr=stderr.read()
ssh.close()
return stdout,stderr
except paramiko.AuthenticationException as exception:
return "Authentication Error trying to connect into the host %s with the user %s. Plese review your keys" % (host, user), e
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--name',
help="Filter result by name.")
parser.add_argument('-t', '--type',
help="Filer result by type.")
parser.add_argument('-s', '--status',
help="Filter result by status." )
parser.add_argument('-e', '--execute',
help="Execute a command on instances")
parser.add_argument('-u', '--user', default="ubuntu",
help="User to run commands if -e option is used.\
Ubuntu user is used by default")
arg = parser.parse_args()
# Default filter if no options are specified
filter=[]
if arg.name:
filter.append({'Name': 'tag-value', 'Values': ["*" + arg.name + "*"]})
if arg.type:
filter.append({'Name': 'instance-type', 'Values': ["*" + arg.type + "*"]})
if arg.status:
filter.append({'Name': 'instance-state-name', 'Values': ["*" + arg.status + "*"]})
hosts=list_instances(filter)
names = ""
if arg.execute:
for item in hosts:
names = names + " " + item["hostname"] + "(" + item["id"] + ")"
print ("\nCommand to execute: %s") % arg.execute
print ("Executed by: %s") % arg.user
print ("Hosts list: %s\n") % names
for item in hosts:
if item["status"] == 'running':
print ("::: %s (%s)") % (item["hostname"], item["id"])
stdout,stderr = execute_cmd(item["ip"], arg.user, arg.execute)
print (stdout)
print (stderr)
else:
print ("::: %s (%s) is not running (command execution skiped)") % (item["hostname"], item["id"])
if __name__ == '__main__':
sys.exit(main())
Excuted from terminal: python ec2-instances.py
and get the below output:
%-3s %-26s %-16s %-16s %-20s %-12s %-12s %-16s
Traceback (most recent call last):
File "ec2-instances.py", line 97, in <module>
sys.exit(main())
File "ec2-instances.py", line 78, in main
hosts=list_instances(filter)
File "ec2-instances.py", line 12, in list_instances
print (columns_format) ("num", "Name", "Public IP", "Private IP", "ID",
"Type", "VPC", "Status")
TypeError: 'NoneType' object is not callable
Thanks in advance for the help!
I think your problem is just that you can't call print like this:
print (columns_format) ("num", "Name", "Public IP", "Private IP", "ID",
"Type", "VPC", "Status")
because print(arguments) (arguments) tries to call a function
try to replace it with (i guess the % just got lost)
print ((columns_format) % ("num", "Name", "Public IP", "Private IP", "ID",
"Type", "VPC", "Status"))
I am using pynetdicom script to fetch the data from the dcm4chee.
to run the script I need to pass the arguments from the command line.
But I already have that value in some variable or in other object and I need to use from there but I am not getting how can I pass that value to the parser or Is it possible to do without parsing.
Please help me to know how can I pass the value using some variables instead of passing through the command line.
Script :
#!/usr/bin/python
"""
For help on usage,
python qrscu.py -h
"""
import argparse
from netdicom.applicationentity import AE
from netdicom.SOPclass import *
from dicom.dataset import Dataset, FileDataset
from dicom.UID import ExplicitVRLittleEndian, ImplicitVRLittleEndian, ExplicitVRBigEndian
import netdicom
import tempfile
# parse commandline
parser = argparse.ArgumentParser(description='storage SCU example')
print "parser", parser
parser.add_argument('remotehost')
parser.add_argument('remoteport', type=int)
parser.add_argument('searchstring')
parser.add_argument('-p', help='local server port', type=int, default=9999)
parser.add_argument('-aet', help='calling AE title', default='PYNETDICOM')
parser.add_argument('-aec', help='called AE title', default='REMOTESCU')
parser.add_argument('-implicit', action='store_true', help='negociate implicit transfer syntax only', default=False)
parser.add_argument('-explicit', action='store_true', help='negociate explicit transfer syntax only', default=False)
args = parser.parse_args()
print "args :::: ", type(args), args
if args.implicit:
ts = [ImplicitVRLittleEndian]
elif args.explicit:
ts = [ExplicitVRLittleEndian]
else:
ts = [
ExplicitVRLittleEndian,
ImplicitVRLittleEndian,
ExplicitVRBigEndian
]
# call back
def OnAssociateResponse(association):
print "Association response received"
def OnAssociateRequest(association):
print "Association resquested"
return True
def OnReceiveStore(SOPClass, DS):
print "Received C-STORE", DS.PatientName
try:
# do something with dataset. For instance, store it.
file_meta = Dataset()
file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here
file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here
filename = '%s/%s.dcm' % (tempfile.gettempdir(), DS.SOPInstanceUID)
ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128)
ds.update(DS)
ds.save_as(filename)
print "File %s written" % filename
except:
pass
# must return appropriate status
return SOPClass.Success
# create application entity with Find and Move SOP classes as SCU and
# Storage SOP class as SCP
MyAE = AE(args.aet, args.p, [PatientRootFindSOPClass,
PatientRootMoveSOPClass,
VerificationSOPClass], [StorageSOPClass], ts)
MyAE.OnAssociateResponse = OnAssociateResponse
MyAE.OnAssociateRequest = OnAssociateRequest
MyAE.OnReceiveStore = OnReceiveStore
MyAE.start()
# remote application entity
RemoteAE = dict(Address=args.remotehost, Port=args.remoteport, AET=args.aec)
# create association with remote AE
print "Request association"
assoc = MyAE.RequestAssociation(RemoteAE)
# perform a DICOM ECHO
print "DICOM Echo ... ",
if assoc:
st = assoc.VerificationSOPClass.SCU(1)
print 'done with status "%s"' % st
print "DICOM FindSCU ... ",
print "\n\n----------------------------------------------------------------------\n\n"
d = Dataset()
d.StudyDate = args.searchstring
d.QueryRetrieveLevel = "STUDY"
d.PatientID = "*"
study = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
print 'done with status "%s"' % st
print "\n\n\n Cont...", study
print "\n\n----------------------------------------------------------------------\n\n"
# loop on patients
for pp in study:
print "\n\n----------------------Pateint Detals------------------------------------------------\n\n"
print "%s - %s" % (pp.StudyDate, pp.PatientID)
# find studies
d = Dataset()
d.PatientID = pp.PatientID
d.QueryRetrieveLevel = "STUDY"
d.PatientName = ""
d.StudyInstanceUID = ""
d.StudyDate = ""
d.StudyTime = ""
d.StudyID = ""
d.ModalitiesInStudy = ""
d.StudyDescription = ""
studies = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
# loop on studies
for st in studies:
print "\n study :: ", studies
print "\n\n---------------------------Study---------------------------\n\n"
print " %s - %s %s" % (st.StudyDescription, st.StudyDate, st.StudyTime)
d = Dataset()
d.QueryRetrieveLevel = "SERIES"
d.StudyInstanceUID = st.StudyInstanceUID
d.SeriesInstanceUID = ""
d.InstanceNumber = ""
d.Modality = ""
d.SeriesNumber = ""
d.SeriesDescription = ""
d.AccessionNumber = ""
d.SeriesDate = ""
d.SeriesTime = ""
d.SeriesID = ""
d.NumberOfSeriesRelatedInstances = ""
series = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
# print series uid and number of instances
if series:
for se in series:
print "\n\n---------------------------Series---------------------------\n\n"
print "\n\n\n series", se
print " %15s - %10s - %35s - %5s" % (se.SeriesNumber, se.Modality, se.SeriesDescription, se.NumberOfSeriesRelatedInstances)
print "Release association"
assoc.Release(0)
# done
MyAE.Quit()
else:
print "Failed to create Association."
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
Put everything inside functions and call them wherever you like:
#!/usr/bin/python
"""
For help on usage,
python qrscu.py -h
"""
import os
import argparse
from netdicom.applicationentity import AE
from netdicom.SOPclass import *
from dicom.dataset import Dataset, FileDataset
from dicom.UID import ExplicitVRLittleEndian, ImplicitVRLittleEndian, ExplicitVRBigEndian
import netdicom
import tempfile
# call back
def OnAssociateResponse(association):
print "Association response received"
def OnAssociateRequest(association):
print "Association resquested"
return True
def OnReceiveStore(SOPClass, DS):
print "Received C-STORE", DS.PatientName
try:
# do something with dataset. For instance, store it.
file_meta = Dataset()
file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here
file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here
filename = os.path.join(tempfile.gettempdir(), DS.SOPInstanceUID + '%s.dcm')
ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128)
ds.update(DS)
ds.save_as(filename)
print "File %s written" % filename
except Exception as e:
print "Some exception occured", e
# must return appropriate status
return SOPClass.Success
def print_data(remotehost, remoteport, searchstring, local_port=9999,
calling_title='PYNETDICOM', called_title='REMOTESCU',
ts=(ExplicitVRLittleEndian, ImplicitVRLittleEndian, ExplicitVRBigEndian)):
# create application entity with Find and Move SOP classes as SCU and
# Storage SOP class as SCP
MyAE = AE(calling_title, local_port, [PatientRootFindSOPClass,
PatientRootMoveSOPClass,
VerificationSOPClass], [StorageSOPClass], ts)
MyAE.OnAssociateResponse = OnAssociateResponse
MyAE.OnAssociateRequest = OnAssociateRequest
MyAE.OnReceiveStore = OnReceiveStore
MyAE.start()
# remote application entity
RemoteAE = dict(Address=remotehost, Port=remoteport, AET=called_title)
# create association with remote AE
print "Request association"
assoc = MyAE.RequestAssociation(RemoteAE)
# perform a DICOM ECHO
print "DICOM Echo ... ",
if not assoc:
print "Failed to create Association."
return
st = assoc.VerificationSOPClass.SCU(1)
print 'done with status "%s"' % st
print "DICOM FindSCU ... ",
print "\n\n----------------------------------------------------------------------\n\n"
d = Dataset()
d.StudyDate = searchstring
d.QueryRetrieveLevel = "STUDY"
d.PatientID = "*"
study = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
print 'done with status "%s"' % st
print "\n\n\n Cont...", study
print "\n\n----------------------------------------------------------------------\n\n"
# loop on patients
for pp in study:
print "\n\n----------------------Pateint Detals------------------------------------------------\n\n"
print "%s - %s" % (pp.StudyDate, pp.PatientID)
# find studies
d = Dataset()
d.PatientID = pp.PatientID
d.QueryRetrieveLevel = "STUDY"
d.PatientName = ""
d.StudyInstanceUID = ""
d.StudyDate = ""
d.StudyTime = ""
d.StudyID = ""
d.ModalitiesInStudy = ""
d.StudyDescription = ""
studies = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
# loop on studies
for st in studies:
print "\n study :: ", studies
print "\n\n---------------------------Study---------------------------\n\n"
print " %s - %s %s" % (st.StudyDescription, st.StudyDate, st.StudyTime)
d = Dataset()
d.QueryRetrieveLevel = "SERIES"
d.StudyInstanceUID = st.StudyInstanceUID
d.SeriesInstanceUID = ""
d.InstanceNumber = ""
d.Modality = ""
d.SeriesNumber = ""
d.SeriesDescription = ""
d.AccessionNumber = ""
d.SeriesDate = ""
d.SeriesTime = ""
d.SeriesID = ""
d.NumberOfSeriesRelatedInstances = ""
series = [x[1] for x in assoc.PatientRootFindSOPClass.SCU(d, 1)][:-1]
# print series uid and number of instances
for se in series:
print "\n\n---------------------------Series---------------------------\n\n"
print "\n\n\n series", se
print " %15s - %10s - %35s - %5s" % (se.SeriesNumber, se.Modality, se.SeriesDescription, se.NumberOfSeriesRelatedInstances)
print "Release association"
assoc.Release(0)
# done
MyAE.Quit()
def parse_commandline():
# parse commandline
parser = argparse.ArgumentParser(description='storage SCU example')
print "parser", parser
parser.add_argument('remotehost')
parser.add_argument('remoteport', type=int)
parser.add_argument('searchstring')
parser.add_argument('-p', help='local server port', type=int, default=9999)
parser.add_argument('-aet', help='calling AE title', default='PYNETDICOM')
parser.add_argument('-aec', help='called AE title', default='REMOTESCU')
parser.add_argument('-implicit', action='store_true', help='negociate implicit transfer syntax only', default=False)
parser.add_argument('-explicit', action='store_true', help='negociate explicit transfer syntax only', default=False)
args = parser.parse_args()
print "args :::: ", type(args), args
if args.implicit:
ts = [ImplicitVRLittleEndian]
elif args.explicit:
ts = [ExplicitVRLittleEndian]
else:
ts = [
ExplicitVRLittleEndian,
ImplicitVRLittleEndian,
ExplicitVRBigEndian
]
return args, ts
if __name__ == '__main__':
args, ts = parse_commandline()
print_data(args.remotehost, args.remoteport, args.searchstring, args.p, args.aet, args.aec, ts)
and use it like:
import your_module
your_module.print_data(remotehost, remoteport, searchstring)
You can incorporate and use the script above in your own code by using the pyhton module subprocess. It will let you run the script with arguments that you define depending on your variables or objects.
Example: Let say that you have some variables your_arg_1...your_arg_n that can be consumed by grscu.py. Then you can pass these variables to the script with
import subprocess
r = subprocess.check_call(['grscu.py', your_arg_1, your_arg_2, ..., your_arg_n])
The "args = parser.parse_args()" in the script will grab the variables and pass them to the MyAE object. For more information about argparse, see link.
I'm getting a buffer error, but I have a line buffer in the 'with open()' block at line 123. Is this the correct location for the buffer? Should I have something in the connects class too/instead, or the parser argument maybe.
I'm trying to use a file with addresses or hostnames using a '--host_file' argument to run the SNMP commands on multiple ASA's. It works using the '--host' argument just fine.
Any help provided would be greatly appreceated.
Traceback (most recent call last):
File "asaos-snmpv3-tool.py", line 145, in <module>
main()
File "asaos-snmpv3-tool.py", line 124, in main
with open(hosts, mode='r', buffering=-1):
TypeError: coercing to Unicode: need string or buffer, file found
import pexpect
import argparse
PROMPT = ['# ', '>>> ', '>', '\$ ']
SNMPGROUPCMD = ' snmp-server group '
V3PRIVCMD = ' v3 priv '
SNMPSRVUSRCMD = ' snmp-server user '
V3AUTHCMD = ' v3 auth '
PRIVCMD = ' priv '
SNMPSRVHOSTCMD = ' snmp-server host '
VERSION3CMD = ' version 3 '
SHAHMACCMD = ' sha '
SNMPSRVENTRAP = ' snmp-server enable traps all '
WRME = ' write memory '
def send_command(child, cmd):
child.sendline(cmd)
child.expect(PROMPT)
print child.before
def connect(user, host, passwd, en_passwd):
ssh_newkey = 'Are you sure you want to continue connecting?'
constr = 'ssh ' + user + '#' + host
child = pexpect.spawn(constr)
ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
if ret == 1:
child.sendline('yes')
ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
child.sendline(passwd)
child.expect(PROMPT)
child.sendline('enable')
child.sendline(en_passwd)
child.expect(PROMPT)
child.sendline('config t')
child.expect(PROMPT)
return child
def connects(user, hosts, passwd, en_passwd):
ssh_newkey = 'Are you sure you want to continue connecting?'
constr = 'ssh ' + user + '#' + hosts
child = pexpect.spawn(constr)
ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
if ret == 1:
child.sendline('yes')
ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
child.sendline(passwd)
child.expect(PROMPT)
child.sendline('enable')
child.sendline(en_passwd)
child.expect(PROMPT)
child.sendline('config t')
child.expect(PROMPT)
return child
def main():
parser = argparse.ArgumentParser('usage %prog ' + '--host --host_file --username --password--enable --group --snmp_user --snmp_host --int_name --snmp_v3_auth --snmp_v3_hmac --snmp_v3_priv --snmp_v3_encr')
parser.add_argument('--host', dest='host', type=str, help='specify a target host')
parser.add_argument('--host_file', dest='hosts', type=file, help='specify a target host file')
parser.add_argument('--username', dest='user', type=str, help='specify a user name')
parser.add_argument('--password', dest='passwd', type=str, help='specify a passwd')
parser.add_argument('--enable', dest='en_passwd', type=str, help='specify an enable passwd')
parser.add_argument('--group', dest='group', type=str, help='specify an snmp group')
parser.add_argument('--snmp_user', dest='snmpuser', type=str, help='specify an snmp user')
parser.add_argument('--snmp_host', dest='snmphost', type=str, help='specify an snmp server host')
parser.add_argument('--int_name', dest='intname', type=str, help='specify interface name')
parser.add_argument('--snmp_v3_auth', dest='snmpauth', type=str, help='specify the snmp user authentication')
parser.add_argument('--snmp_v3_hmac', dest='snmphmac', type=str, help='set snmp HMAC, md5 or sha')
parser.add_argument('--snmp_v3_priv', dest='snmppriv', type=str, help='specify the snmp priv password')
parser.add_argument('--snmp_v3_encr', dest='snmpencrypt', type=str, help='specify encryption, des, 3des, or aes(128/192/256)')
args = parser.parse_args()
host = args.host
hosts = args.hosts
user = args.user
passwd = args.passwd
en_passwd = args.en_passwd
group = args.group
snmpuser = args.snmpuser
snmphost = args.snmphost
intname = args.intname
snmpauth = args.snmpauth
snmppriv = args.snmppriv
snmpencrypt = args.snmpencrypt
if hosts:
with open(hosts, mode='r', buffering=1):
for line in hosts:
hosts = line.rstrip
child = connects(user, hosts, passwd, en_passwd)
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
send_command(child, SNMPSRVENTRAP)
send_command(child, WRME)
elif host:
child = connect(user, host, passwd, en_passwd)
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
send_command(child, SNMPSRVENTRAP)
send_command(child, WRME)
else:
print ('Specify either --host or --host_file or I have nothing to do')
if __name__ == '__main__':
main()
There are a whole series of problems here:
if hosts:
with open(hosts, mode='r', buffering=1):
Here, hosts is clearly meant to be a filename. You open that file… and then don't store it in a variable anywhere, and go on to use the filename as if it were a file.
But, before you even get there, hosts is not actually a filename. One of the nifty features of argparse is that it can automatically open files for you, and you're asking it to do that by using type=file in the argument spec. Which means that hosts is actually a file object, and you're trying to use that file object itself as a filename! Which is what' actually causing the TypeError: coercing to Unicode: need string or buffer, file found: open tries to convert filenames to Unicode strings, and it has no idea how to do that with a file object. If you want to open hosts, don't tell argparse to do it for you; just leave its type as a str.
for line in hosts:
Since hosts is supposed to be a filename, as a string, this will give you each character in the filename, as a string. Which is not useful.
hosts = line.rstrip
This overwrites the hosts variable, which you need. And, even worse, it overwrites it with the bound method line.rstrip, rather than the result of calling line.rstrip.
child = connects(user, hosts, passwd, en_passwd)
And here, you're passing that bound method to a function that wants a string, which isn't going to work.
Don't keep using the same variable name over and over to mean different things. Use a different name for each thing. Ideally one whose name relates in some way to the thing it's holding. For example, a ech (stripped) line in a file named hosts is probably a host, or a hosts_entry… one thing it's not is all of your hosts.
Anyway, to fix all of these problems:
if hosts:
for line in hosts:
host = line.rstrip()
child = connects(user, host, passwd, en_passwd)
Or, if you want to control how hosts is being opened (I'm not sure why you think it's important to specify buffering=1, but presumably you have some reason?):
parser.add_argument('--host_file', dest='hosts', type=str, help='specify a target host file')
# …
if hosts:
with open(hosts, buffering=1) as hosts_file:
for line in hosts_file:
host = line.rstrip()
child = connects(user, host, passwd, en_passwd)
it looks like you're iterating over the wrong thing here:
with open(hosts, mode='r', buffering=1):
for line in hosts:
hosts = line.rstrip
You maybe want this:
with open(hosts, mode='r', buffering=1) as lines:
for line in lines:
host = line.rstrip
I'm new to Ubuntu (and the Python scripts that go with it) and I've been hitting this error with the iTunesToRhythm script.
**Traceback (most recent call last):
File "/home/amylee/iTunesToRhythm.py", line 220, in <module>
main(sys.argv)
File "/home/amylee/iTunesToRhythm.py", line 48, in main
match = correlator.correlateSong( song, options.confirm, options.fastAndLoose, options.promptForDisambiguate )
File "/home/amylee/iTunesToRhythm.py", line 133, in correlateSong
matches = self.parser.findSongBySize( song.size );
AttributeError: 'NoneType' object has no attribute 'findSongBySize'**
I understand the concept behind fixing the issue but have no idea how to go about it. I've looked at answers to similar problems but none really help me, especially since I have no clue as to what I am doing. I've included the full script below. Thanks in advance, dudes who know way more about this stuff than I do.
----iTunesToRhythm.py----
import sys
import platform
if platform.system() == "Darwin":
sys.path.append('/sw/lib/python2.5/site-packages/')
from dumpitunesmac import iTunesMacParser, iTunesMacSong
import libxml2
import linecache
from optparse import OptionParser, OptionGroup
from dumprhythm import RhythmLibraryParser, RhythmSong
from dumpitunes import iTunesLibraryParser, iTunesSong
def main(argv):
# process command line
options, args = processCommandLine(argv)
print "Reading input from " + args[0]
inputParser = getParser(args[0], options )
print "Writing to output " + args[1]
destinationParser = getParser(args[1], options )
#retrieve destination songs
allDestinationSongs = destinationParser.getSongs()
# go through each song in destination library
correlator = SongCorrelator(inputParser)
for song in allDestinationSongs:
print song.artist + " - " + song.album + " - " + song.title + " - " + str(song.size)
if song.size != None and song.size != "Unknown":
# find equivalent itunes song
match = correlator.correlateSong( song, options.confirm, options.fastAndLoose, options.promptForDisambiguate )
# update database, if match
if match != None and options.writeChanges == True:
if options.noratings == False:
song.setRating( match.rating )
print "\t\t\tRating changed to " + str( match.rating )
if options.noplaycounts == False:
song.setPlaycount( match.playcount )
print "\t\t\tPlay count changed to " + str( match.playcount )
# dump summary results
print "\nSummary\n------------------------------------"
print "manually resolved matches = " + str( correlator.manuallyResolvedMatches)
print "full matches = " + str( correlator.fullMatches )
print "partial matches = " + str( correlator.partialMatches)
print "no matches = " + str( correlator.zeroMatches )
print "unresolved ambiguous matches = " + str( correlator.ambiguousMatches )
# save
if options.writeChanges == True:
destinationParser.save()
print "Changes were written to destination"
else:
print "Changes were not written to destination \n\tuse -w to actually write changes to disk"
def getParser( file, options ):
if file == "mysql":
print "\tassuming amarok database"
return AmarokLibraryParser(options.servername, options.database, options.username, options.password )
if file == "itunes":
print "\tassuming itunes on the mac"
return iTunesMacParser()
desc = linecache.getline( file, 2)
if desc.find("Apple Computer") != -1:
#open itunes linbrary
print "\tdetected Itunes library"
return iTunesLibraryParser(file);
if desc.find("rhythmdb") != -1:
print "\tdetected Rhythm box library"
return RhythmLibraryParser(file)
def processCommandLine( argv ):
parser = OptionParser("iTunesToRhythm [options] <inputfile>|itunes|mysql <outputfile>|mysql|itunes")
parser.add_option("-c", "--confirm", action="store_true", dest="confirm", default = False, help="confirm every match" )
parser.add_option("-w", "--writechanges", action="store_true", dest="writeChanges", default = False, help="write changes to destination file" )
parser.add_option("-a", "--disambiguate", action="store_true", dest="promptForDisambiguate", default = False, help="prompt user to resolve ambiguities" )
parser.add_option("-l", "--fastandloose", action="store_true", dest= "fastAndLoose", default = False, help = "ignore differences in files name when a file size match is made against a single song. Will not resolve multiple matches" )
parser.add_option("--noplaycounts", action="store_true", dest= "noplaycounts", default = False, help = "do not update play counts" )
parser.add_option("--noratings", action="store_true", dest= "noratings", default = False, help = "do not update ratings" )
amarokGroup = OptionGroup(parser, "Amarok options", "Options for connecting to an Amarok MySQL remote database")
amarokGroup.add_option("-s", "--server", dest="servername", help = "host name of the MySQL database server")
amarokGroup.add_option("-d", "--database", dest="database", help = "database name of the amarok database")
amarokGroup.add_option("-u", "--username", dest="username", help = "login name of the amarok database")
amarokGroup.add_option("-p", "--password", dest="password", help = "password of the user")
parser.add_option_group(amarokGroup)
# parse options
options, args = parser.parse_args()
# check that files are specified
if len(args) != 2:
parser.print_help()
parser.error( "you must supply 2 file names or 1 file name and the word mysql followed by database information. Specyfing itunes will use a running instance of iTunes on the Mac" )
# make surce source & destination are not the same
if args[0] == args[1]:
parser.error("source and destination cannot be the same")
# we're ok
return options, args
class SongCorrelator:
def __init__(self, parser ):
self.parser = parser
self.zeroMatches = 0
self.fullMatches = 0
self.ambiguousMatches = 0;
self.partialMatches = 0;
self.manuallyResolvedMatches = 0;
# attempt to find matching song in database
def correlateSong( self, song, confirm, fastAndLoose, promptForDisambiguate ):
match = None
matches = self.parser.findSongBySize( song.size );
matchcount = len(matches)
# no results
if matchcount == 0:
print "\t no matches found"
self.zeroMatches = self.zeroMatches + 1
# full match
elif matchcount == 1:
match = matches[0]
if match.title == song.title:
print "\t 100% match on " + self.dumpMatch( match )
self.fullMatches = self.fullMatches + 1
else:
if fastAndLoose == False:
match = self.disambiguate( song, matches, promptForDisambiguate )
else:
print "\t 50% match on " + self.dumpMatch( match )
self.partialMatches = self.partialMatches + 1
# multiple matches
else:
print "\t multiple matches"
for match in matches:
print "\t\t " + self.dumpMatch( match )
# attempt a resolution
match = self.disambiguate( song, matches, promptForDisambiguate )
#review
if confirm == True:
foo = raw_input( 'press <enter> to continue, Ctrl-C to cancel')
#done
return match
def dumpMatch( self, match ):
return match.title + ", playcount = " + str(match.playcount) + ", rating = " + str(match.rating)
def disambiguate(self,song,matches,prompt):
# attempt to disambiguate by title
print "\t looking for secondary match on title"
titlematchcount = 0
for match in matches:
if match.title == song.title:
titlematchcount = titlematchcount + 1
latstitlematch = match
if titlematchcount == 1:
# we successfully disambiguated using the title
print "\t\t disambiguated using title"
self.fullMatches = self.fullMatches + 1
return latstitlematch
if prompt == True:
print "\t\t cannot disambiguate. Trying to match " + song.filePath
print "Please select file or press <Enter> for no match:"
numMatch = 0
for match in matches:
numMatch = numMatch + 1
print "\t\t\t\t[" + str(numMatch) + "] " + self.dumpMatch(match) + ", " + match.filePath
selection = self.inputNumber("\t\t\t\t? ", 1, len(matches) )
if selection > 0:
self.manuallyResolvedMatches = self.manuallyResolvedMatches + 1
return matches[selection - 1]
# user did not select, record ambiguity
self.ambiguousMatches = self.ambiguousMatches + 1
return None
def inputNumber(self, msg, min, max):
result = raw_input(msg)
if len(result) == 0:
return 0
try:
resultNum = int(result)
if resultNum < min or resultNum > max:
print "out of range"
return self.inputNumber( msg, min, max )
return resultNum
except:
print "invalid input"
return self.inputNumber(msg, min, max)
if __name__ == "__main__":
main(sys.argv)
I'm the original developer. I updated the script to throw an exception if the file format is not recognized (I think this is what you are running into). I also incorporated some useful patches from another user.
Please download the files again and e-mail me if you still have trouble.
Your problem appears to be that getParser is returning None, presumably because all the if conditions have failed.
Check that args[0] and options are the values that you expect them to be.
I'd suggest raising an exception at the end of the getParser method if the arguments are not valid so that the error is raised close to the cause of the problem rather in some unrelated code much later.