Python script to parse 'iwlist scan' into a table
Hi,
I've written a small python script that parses the output of the command "iwlist interface scan" into a table.
Why ?
Like many arch linux users I think, I use netcfg instead of something like network manager or wicd. So the most natural way to scan for wifi networks in range is iwlist scan. But the output of this command is huge and I find it difficult to retrieve information. So this script parses it into a table : one network, one line.
Example output
Name Address Quality Channel Encryption
wifi_1 01:23:45:67:89:AB 100 % 11 WPA v.1
wifi_2 01:23:45:67:89:AC 76 % 11 WEP
wifi_3 01:23:45:67:89:AD 51 % 11 Open
wifi_4 01:23:45:67:89:AE 50 % 11 WPA v.1
wifi_5 01:23:45:67:89:AF 43 % 4 Open
wifi_6 01:23:45:67:89:AG 43 % 4 WPA v.1
Details
It reads from stdin so you use it like that: iwlist wlan0 scan | iwlistparse.py
The width of the columns is determined by what's in it.
You can easily do a bit more than just parsing the info: in the example above, the quality has been calculated to percents from a ratio (e.g. 46/70).
It is sorted, too.
Customization
It's python so it's easy to customize. See the comments in the code.
Code
#!/usr/bin/env python
# iwlistparse.py
# Hugo Chargois - 17 jan. 2010 - v.0.1
# Parses the output of iwlist scan into a table
import sys
# You can add or change the functions to parse the properties of each AP (cell)
# below. They take one argument, the bunch of text describing one cell in iwlist
# scan and return a property of that cell.
def get_name(cell):
return matching_line(cell,"ESSID:")[1:-1]
def get_quality(cell):
quality = matching_line(cell,"Quality=").split()[0].split('/')
return str(int(round(float(quality[0]) / float(quality[1]) * 100))).rjust(3) + " %"
def get_channel(cell):
return matching_line(cell,"Channel:")
def get_encryption(cell):
enc=""
if matching_line(cell,"Encryption key:") == "off":
enc="Open"
else:
for line in cell:
matching = match(line,"IE:")
if matching!=None:
wpa=match(matching,"WPA Version ")
if wpa!=None:
enc="WPA v."+wpa
if enc=="":
enc="WEP"
return enc
def get_address(cell):
return matching_line(cell,"Address: ")
# Here's a dictionary of rules that will be applied to the description of each
# cell. The key will be the name of the column in the table. The value is a
# function defined above.
rules={"Name":get_name,
"Quality":get_quality,
"Channel":get_channel,
"Encryption":get_encryption,
"Address":get_address,
# Here you can choose the way of sorting the table. sortby should be a key of
# the dictionary rules.
def sort_cells(cells):
sortby = "Quality"
reverse = True
cells.sort(None, lambda el:el[sortby], reverse)
# You can choose which columns to display here, and most importantly in what order. Of
# course, they must exist as keys in the dict rules.
columns=["Name","Address","Quality","Channel","Encryption"]
# Below here goes the boring stuff. You shouldn't have to edit anything below
# this point
def matching_line(lines, keyword):
"""Returns the first matching line in a list of lines. See match()"""
for line in lines:
matching=match(line,keyword)
if matching!=None:
return matching
return None
def match(line,keyword):
"""If the first part of line (modulo blanks) matches keyword,
returns the end of that line. Otherwise returns None"""
line=line.lstrip()
length=len(keyword)
if line[:length] == keyword:
return line[length:]
else:
return None
def parse_cell(cell):
"""Applies the rules to the bunch of text describing a cell and returns the
corresponding dictionary"""
parsed_cell={}
for key in rules:
rule=rules[key]
parsed_cell.update({key:rule(cell)})
return parsed_cell
def print_table(table):
widths=map(max,map(lambda l:map(len,l),zip(*table))) #functional magic
justified_table = []
for line in table:
justified_line=[]
for i,el in enumerate(line):
justified_line.append(el.ljust(widths[i]+2))
justified_table.append(justified_line)
for line in justified_table:
for el in line:
print el,
print
def print_cells(cells):
table=[columns]
for cell in cells:
cell_properties=[]
for column in columns:
cell_properties.append(cell[column])
table.append(cell_properties)
print_table(table)
def main():
"""Pretty prints the output of iwlist scan into a table"""
cells=[[]]
parsed_cells=[]
for line in sys.stdin:
cell_line = match(line,"Cell ")
if cell_line != None:
cells.append([])
line = cell_line[-27:]
cells[-1].append(line.rstrip())
cells=cells[1:]
for cell in cells:
parsed_cells.append(parse_cell(cell))
sort_cells(parsed_cells)
print_cells(parsed_cells)
main()
I hope you find it useful. Please report bugs, I haven't tested it a lot. You may have to customize it though, because I think not all iwlist scan outputs are the same. Again, see comments, it should be easy.
This tool is very helpfull. I am trying to add a new function to the existing code to parse the signal level parameter from the output of iwlist wlan0 scan, but I am getting lot of issues .Since I am new to python script can anyone help me to extract the signal level also from the scan put put.
The parametr to be used is Signal level=-44 dBm ,I am trying to create a one more column with Signal level and print its out in the table.
Example:-
Signal level
-44db
The error I am getting
File "iwlist_parser_Testing.py", line 146, in <module>
main()
File "iwlist_parser_Testing.py", line 144, in main
print_cells(parsed_cells)
File "iwlist_parser_Testing.py", line 123, in print_cells
print_table(table)
File "iwlist_parser_Testing.py", line 102, in print_table
widths=map(max,map(lambda l:map(len,l),zip(*table))) #functional magic
File "iwlist_parser_Testing.py", line 102, in <lambda>
widths=map(max,map(lambda l:map(len,l),zip(*table))) #functional magic
TypeError: object of type 'NoneType' has no len()
Could some pls help me to solve this issue
Thanks
Similar Messages
-
Script for parsing xml data and inserting in DB
Thank you for reading.
I have the following example XML in an XML file. I need to write a script that can insert this data into an Oracle table. The table does not have primary keys. The data just needs to be inserted.
I do not have xsd file in this scenario. Please suggest how to modify Method 1 https://community.oracle.com/thread/1115266?tstart=0 mentioned so that I can call the XML mentioned below and insert into a table
Method 1
Create or replace procedure parse_xml is
l_bfile BFILE;
l_clob CLOB;
l_parser dbms_xmlparser.Parser;
l_doc dbms_xmldom.DOMDocument;
l_nl dbms_xmldom.DOMNodeList;
l_n dbms_xmldom.DOMNode;
l_file dbms_xmldom.DOMNodeList;
l_filen dbms_xmldom.DOMNode;
lv_value VARCHAR2(1000);
l_ch dbms_xmldom.DOMNode;
l_partname varchar2(100);
l_filename varchar2(1000);
l_temp VARCHAR2(1000);
TYPE tab_type IS TABLE OF tab_software_parts%ROWTYPE;
t_tab tab_type := tab_type();
BEGIN
l_bfile := BFileName('DIR1', 'SoftwareParts.xml');
dbms_lob.createtemporary(l_clob, cache=>FALSE);
dbms_lob.open(l_bfile, dbms_lob.lob_readonly);
dbms_lob.loadFromFile(dest_lob => l_clob, src_lob => l_bfile, amount => dbms_lob.getLength(l_bfile));
dbms_lob.close(l_bfile);
dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MON-YYYY''');
l_parser := dbms_xmlparser.newParser;
dbms_xmlparser.parseClob(l_parser, l_clob);
l_doc := dbms_xmlparser.getDocument(l_parser);
dbms_lob.freetemporary(l_clob);
dbms_xmlparser.freeParser(l_parser);
l_nl := dbms_xslprocessor.selectNodes(dbms_xmldom.makeNode(l_doc),'/PartDetails/Part');
FOR cur_emp IN 0 .. dbms_xmldom.getLength(l_nl) - 1 LOOP
l_n := dbms_xmldom.item(l_nl, cur_emp);
t_tab.extend;
dbms_xslprocessor.valueOf(l_n,'Name/text()',l_partname);
t_tab(t_tab.last).partname := l_partname;
l_file := dbms_xslprocessor.selectNodes(l_n,'Files/FileName');
FOR cur_ch IN 0 .. dbms_xmldom.getLength(l_file) - 1 LOOP
l_ch := dbms_xmldom.item(l_file, cur_ch);
lv_value := dbms_xmldom.getnodevalue(dbms_xmldom.getfirstchild(l_ch));
if t_tab(t_tab.last).partname is null then t_tab(t_tab.last).partname := l_partname; end if;
t_tab(t_tab.last).filename := lv_value;
t_tab.extend;
END LOOP;
END LOOP;
t_tab.delete(t_tab.last);
FOR cur_emp IN t_tab.first .. t_tab.last LOOP
if t_tab(cur_emp).partname is not null and t_tab(cur_emp).filename is not null then
INSERT INTO tab_software_parts
VALUES
(t_tab(cur_emp).partname, t_tab(cur_emp).filename);
end if;
END LOOP;
COMMIT;
dbms_xmldom.freeDocument(l_doc);
EXCEPTION
WHEN OTHERS THEN
dbms_lob.freetemporary(l_clob);
dbms_xmlparser.freeParser(l_parser);
dbms_xmldom.freeDocument(l_doc);
END;
<TWObject className="TWObject">
<array size="240">
<item>
<variable type="QuestionDetail">
<questionId type="String"><![CDATA[30]]></questionId>
<questionType type="questionType"><![CDATA[COUNTRY]]></questionType>
<country type="String"><![CDATA[GB]]></country>
<questionText type="String"><![CDATA[Please indicate]]></questionText>
<optionType type="String"><![CDATA[RadioButton]]></optionType>
<answerOptions type="String[]">
<item><![CDATA[Yes]]></item>
<item><![CDATA[No]]></item>
</answerOptions>
<ruleId type="String"><![CDATA[CRP_GB001]]></ruleId>
<parentQuestionId type="String"></parentQuestionId>
<parentQuestionResp type="String"></parentQuestionResp>
</variable>
</item>
<item>
<variable type="QuestionDetail">
<questionId type="String"><![CDATA[40]]></questionId>
<questionType type="questionType"><![CDATA[COUNTRY]]></questionType>
<country type="String"><![CDATA[DE]]></country>
<questionText type="String"><![CDATA[Please indicate]]></questionText>
<optionType type="String"><![CDATA[RadioButton]]></optionType>
<answerOptions type="String[]">
<item><![CDATA[Yes]]></item>
<item><![CDATA[No]]></item>
</answerOptions>
<ruleId type="String"><![CDATA[CRP_Q0001]]></ruleId>
<parentQuestionId type="String"></parentQuestionId>
<parentQuestionResp type="String"></parentQuestionResp>
</variable>
</item>
</array>
</TWObject>Reposted as
Script to parse XML data into Oracle DB -
How to load a XML file into a table
Hi,
I've been working on Oracle for many years but for the first time I was asked to load a XML file into a table.
As an example, I've found this on the web, but it doesn't work
Can someone tell me why? I hoped this example could help me.
the file acct.xml is this:
<?xml version="1.0"?>
<ACCOUNT_HEADER_ACK>
<HEADER>
<STATUS_CODE>100</STATUS_CODE>
<STATUS_REMARKS>check</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>2</SEGMENT_NUMBER>
<REMARKS>rp polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>3</SEGMENT_NUMBER>
<REMARKS>rp polytechnic administration</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>4</SEGMENT_NUMBER>
<REMARKS>rp polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>5</SEGMENT_NUMBER>
<REMARKS>rp polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
<HEADER>
<STATUS_CODE>500</STATUS_CODE>
<STATUS_REMARKS>process exception</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>20</SEGMENT_NUMBER>
<REMARKS> base polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>30</SEGMENT_NUMBER>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>40</SEGMENT_NUMBER>
<REMARKS> base polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>50</SEGMENT_NUMBER>
<REMARKS> base polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
</ACCOUNT_HEADER_ACK>
For the two tags HEADER and DETAILS I have the table:
create table xxrp_acct_details(
status_code number,
status_remarks varchar2(100),
segment_number number,
remarks varchar2(100)
before I've created a
create directory test_dir as 'c:\esterno'; -- where I have my acct.xml
and after, can you give me a script for loading data by using XMLTABLE?
I've tried this but it doesn't work:
DECLARE
acct_doc xmltype := xmltype( bfilename('TEST_DIR','acct.xml'), nls_charset_id('AL32UTF8') );
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS[$hn]/DETAIL'
passing acct_doc as "d",
x1.header_no as "hn"
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
END;
This should allow me to get something like this:
select * from xxrp_acct_details;
Statuscode status remarks segement remarks
100 check 2 rp polytechnic
100 check 3 rp polytechnic administration
100 check 4 rp polytechnic finance
100 check 5 rp polytechnic logistics
500 process exception 20 base polytechnic
500 process exception 30
500 process exception 40 base polytechnic finance
500 process exception 50 base polytechnic logistics
but I get:
Error report:
ORA-06550: line 19, column 11:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got NUMBER
ORA-06550: line 4, column 2:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
and if I try to change the script without using the column HEADER_NO to keep track of the header rank inside the document:
DECLARE
acct_doc xmltype := xmltype( bfilename('TEST_DIR','acct.xml'), nls_charset_id('AL32UTF8') );
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'/ACCOUNT_HEADER_ACK/DETAILS'
passing acct_doc
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
END;
I get this message:
Error report:
ORA-19114: error during parsing the XQuery expression:
ORA-06550: line 1, column 13:
PLS-00201: identifier 'SYS.DBMS_XQUERYINT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at line 4
19114. 00000 - "error during parsing the XQuery expression: %s"
*Cause: An error occurred during the parsing of the XQuery expression.
*Action: Check the detailed error message for the possible causes.
My oracle version is 10gR2 Express Edition
I do need a script for loading xml files into a table as soon as possible, Give me please a simple example for understanding and that works on 10gR2 Express Edition
Thanks in advance!The reason your first SQL statement
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS[$hn]/DETAIL'
passing acct_doc as "d",
x1.header_no as "hn"
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
returns the error you noticed
PL/SQL: ORA-00932: inconsistent datatypes: expected - got NUMBER
is because Oracle is expecting XML to be passed in. At the moment I forget if it requires a certain format or not, but it is simply expecting the value to be wrapped in simple XML.
Your query actually runs as is on 11.1 as Oracle changed how that functionality worked when 11.1 was released. Your query runs slowly, but it does run.
As you are dealing with groups, is there any way the input XML can be modified to be like
<ACCOUNT_HEADER_ACK>
<ACCOUNT_GROUP>
<HEADER>....</HEADER>
<DETAILS>....</DETAILS>
</ACCOUNT_GROUP>
<ACCOUNT_GROUP>
<HEADER>....</HEADER>
<DETAILS>....</DETAILS>
</ACCOUNT_GROUP>
</ACCOUNT_HEADER_ACK>
so that it is easier to associate a HEADER/DETAILS combination? If so, it would make parsing the XML much easier.
Assuming the answer is no, here is one hack to accomplish your goal
select x1.status_code,
x1.status_remarks,
x3.segment_number,
x3.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS'
passing acct_doc as "d",
columns detail_no for ordinality,
detail_xml xmltype path 'DETAIL'
) x2,
xmltable(
'DETAIL'
passing x2.detail_xml
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS') x3
WHERE x1.header_no = x2.detail_no;
This follows the approach you started with. Table x1 creates a row for each HEADER node and table x2 creates a row for each DETAILS node. It assumes there is always a one and only one association between the two. I use table x3, which is joined to x2, to parse the many DETAIL nodes. The WHERE clause then joins each header row to the corresponding details row and produces the eight rows you are seeking.
There is another approach that I know of, and that would be using XQuery within the XMLTable. It should require using only one XMLTable but I would have to spend some time coming up with that solution and I can't recall whether restrictions exist in 10gR2 Express Edition compared to what can run in 10.2 Enterprise Edition for XQuery. -
Run Python Script in Automator
I have a python script (which was written for me), and I would like to make it so that the script executes every x minutes. I know this should be simple to do, but I can't figure it out.
Thus far, I have created a workflow in automator, used the "Run Shell Script" action, and pasted the script into the text field.
"Workflow failed - 1 error
I'm very new to this, so I'm sure it's a simple error. Any help would great.
Here is the script I am trying to execute.
#!/Library/Frameworks/Python.framework/Versions/2.7/bin/python
# you can change the above line to point to the location of python
# on your system (you can check this by typing 'which python' into
# Terminal.app), but this isn't necessary if you execute the script
# using "python ksl.py [URL]"
# change the value of NAME to your desired name
NAME = "Bob Jones"
# change the value of EMAIL to your desired email
EMAIL = "[email protected]"
# your message will be the contact name as mined from the page source,
# followed by whatever message you enter between the following triple quotes
MESSAGE = """Replace this text with your message. Newlines are also OK."""
import mechanize
import re
import sys
def setupBrowser(url):
b = mechanize.Browser()
# b.sethandlerobots(False)
# b.addheaders = [('User-agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)')]
try:
b.open(url)
except mechanize._mechanize.BrowserStateError:
print >> sys.stderr, "You have mistyped the URL. It must by in the following format, including the quotes and the preceding 'http://':\n\t %s [--test] 'http://www.blah.com'" % (sys.argv[0])
sys.exit(1)
return b
def grabLinks(b):
"""Takes in a mechanize.Browser() object pointed to a listings URL and returns a listing of classified ad links."""
links = []
for link in b.links():
# change this line if the URL format ever changes
if re.search(r'&ad=', link.url):
links.append(mechanize.urljoin(link.base_url, link.url))
return links
if _name_ == '_main_':
# check for proper command line args
if len(sys.argv) != 2 and len(sys.argv) != 3:
print >> sys.stderr, "Usage: %s [--test] url" % (sys.argv[0])
sys.exit(1)
args = sys.argv[1:]
if len(args) == 1:
# start from listings page
url = args[0]
# set up the mechanize browser object
b = setupBrowser(url)
# grab only the relevant ad links
links = grabLinks(b)
if not links or len(links) == 0:
# the links do not follow the same format as the original page
print >> sys.stderr, "The link format has changed, or you have mistyped the URL."
sys.exit(1)
# open the first link on the listings page
b.open(links[0])
else:
# start from a single listing
if args[0] != "--test":
print >> sys.stderr, "Usage %s [--test] url"
sys.exit(1)
url = args[1]
b = setupBrowser(url)
# grab the HTML so that we can search for the contact name
response = b.response().get_data()
# perform a regex search on the HTML for the contact name
regexSearch = re.search(r'Contact Name:\s*\s(w+)s', response)
contactName = ""
if regexSearch:
# contact name found -- store it
contactName = regexSearch.group(1)
else:
# contact name not found -- use generic greeting
contactName = "Hello"
theOne = ""
# find the "Email Seller" link (stored as "theOne")
for link in b.links():
# again, if the URL changes, change this line
if re.search(r'xmldb=', link.url):
theOne = mechanize.urljoin(link.base_url, link.url)
if theOne == "":
# something went wrong
print >> sys.stderr, "'Email Seller' link has changed formats within the HTML."
sys.exit(1)
b.open(theOne)
# fill out the forms. note that I am grabbing the SECOND form here.
# again, this might change over time, so feel free to change this from
# nr=1 to nr=0 (for the first form), nr=2 (for the third form), etc.
b.select_form(nr=1)
b['form_4'] = NAME
b['form_5'] = EMAIL
# append the contact name to the rest of the message
MESSAGE = contactName + """,\n\n""" + MESSAGE
b['form_6'] = MESSAGE
# submit the form
b.submit()
b.close()If the script works, and all you need is to execute every x minutes, use launchd, and its simple to write with the Lingon GUI: http://sourceforge.net/projects/lingon/files/
-
Call an ABAP program or a function module from command prompt/python script
Dear All,
I want to call a function module/ABAP program from command prompt or a python script.
Let me explain with an example.
There is a function module "z_add" that takes two integers as input parameters and generates their sum.
the sum is the output parameter.
Now i want to call this function module from command prompt / python script and pass parameters to this function module.
In return i must get the sum(i.e. the output of function module).
I tried using STARTRFC ,was able to call the FM but could not get the return value(output) from FM.
Can you please provide me the code of such a function module and the method to call it thereby passing parameters and getting the sum.
Thanks and regards,
Gaurav
Edited by: gauravkec2005 on Mar 4, 2010 7:41 AMthank you both! helpful answers! :o)
anyway!
i have written the program which is called from the SAPScript:
/: PERFORM GET_VATNUMBER IN PROGRAM ZFI_F140_OPERATIONS
/: USING &BKPF-BUKRS&
/: CHANGING &VATNUMBER&
CE VAT Registration No : &VATNUMBER&
REPORT zfi_f140_operations.
FORM get_vatnumber TABLES in_par STRUCTURE itcsy
out_par STRUCTURE itcsy.
DATA: lv_co_code TYPE bukrs,
lv_vat_no TYPE stceg.
READ TABLE in_par WITH KEY name = 'BKPF-BUKRS'.
MOVE in_par-value TO lv_co_code.
SELECT SINGLE stceg FROM t001
INTO lv_vat_no WHERE bukrs = lv_co_code.
out_par-name = 'VATNUMBER'.
WRITE lv_vat_no TO out_par-value.
CONDENSE out_par-value.
MODIFY out_par INDEX 1.
ENDFORM.
it is not working and i cannot work out why...
i have not been ABAPing for very long but have had a go....
any thoughts as to what i have done wrong?
or point me where i should be looking? thank you! -
Python Script to Generate MySQL Stored Routines
Here is a quick Python script that reads a MySQL scheme (database) and for each table, it generates Insert, Update, Get and Delete stored routines. The script is just a "quick-n-dirty" script, but it does take into account that the Update, Get and Delete routines need to key off the primary key (and if there's not one, there could be trouble!). Each stored routine is output into a separate file.
I'm attaching the script so you professional Python people can tell me where I could improve the script with respect to simplicity, readability, cleanliness, etc.
I have NOT yet got the command line parameters added to this script, but plan to soon.
#!/usr/bin/env python
# spgen.py
# Copyright 2008 Matt Runion <[email protected]>
import sys
import MySQLdb
# The INSERT template
insertTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
INSERT INTO %s (
%s
) VALUES (
%s
END$$
DELIMITER ;
# The UPDATE template
updateTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
UPDATE %s SET
%s
WHERE
%s;
END$$
DELIMITER ;
# The GET template
getTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
SELECT
%s
FROM %s
WHERE
%s;
END$$
DELIMITER ;
# The DELETE template
deleteTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
DELETE FROM %s
WHERE
%s;
END$$
DELIMITER ;
def generateSPs(dbhost, dbname, dbuser, dbpasswd):
This method reads all the tables from the database and for each of them
generates the following stored routines:
<TableName>_Insert
<TableName>_Update
<TableName>_Get
<TableName>_Delete
# Open the database connection
print 'Connecting to database [%s] on host [%s]' % (dbname, dbhost)
dbConn = MySQLdb.connect(host=dbhost, user=dbuser, passwd=dbpasswd, db=dbname)
cur = dbConn.cursor()
# Get a list of all tables in the database
print 'Reading tables...'
cur.execute("SHOW TABLES FROM %s" % dbname)
tables = cur.fetchall()
for table in tables:
print 'Generating stored procs for table [%s]...' % table[0]
# Get a list of a columns in the current table
cur.execute("SHOW COLUMNS FROM %s" % table[0])
columns = cur.fetchall()
insertUpdateParms = ''
getDeleteParms = ''
whereClause = ''
insertList = ''
valuesList = ''
updateList = ''
for column in columns:
# Reset some variables
print ' %s -- %s [%s, %s, %s]' % (column[0], column[1], column[2], column[3], column[4])
# Append the columns to the input parms
if (len(insertUpdateParms) > 0):
insertUpdateParms += ',\n'
insertList += ',\n'
valuesList += ',\n'
if (len(updateList) > 0):
updateList += ',\n'
insertUpdateParms += '%sIN ' % column[0]
if ((column[1][0:3].lower() == 'var') or (column[1][0:3].lower() == 'cha')):
insertUpdateParms += '%s' % column[1]
elif (column[1][0:3].lower() == 'enu'):
insertUpdateParms += 'varchar(50)'
else:
insertUpdateParms += (column[1].split('('))[0]
insertList += column[0]
valuesList += '%sIN' % column[0]
# Generate the key parms that are used for the Get and Delete
# stored procs, and generate the values for the WHERE clause
# for the Update, Get and Delete stored procs
if (column[3].lower() == 'pri'):
if (len(getDeleteParms) > 0):
getDeleteParms += ',\n'
getDeleteParms += '%sIN ' % column[0]
if (column[1][0:3].lower() == 'var'):
getDeleteParms += '%s' % column[1]
else:
getDeleteParms += (column[1].split('('))[0]
if (len(whereClause) > 0):
whereClause += ' AND \n'
whereClause += '%s = %sIN' % (column[0], column[0])
else:
updateList += '%s = %sIN' % (column[0], column[0])
#print '---'
#print insertUpdateParms
#print '---'
#print getDeleteParms
#print '---'
#print whereClause
#print 'INSERT:'
#print insertTemplate % (table[0] + '_Insert', table[0] + '_Insert', insertUpdateParms, table[0], insertList, valuesList)
#print 'UPDATE:'
#print updateTemplate % (table[0] + '_Update', table[0] + '_Update', insertUpdateParms, table[0], updateList, whereClause)
#print 'GET:'
#print getTemplate % (table[0] + '_Get', table[0] + '_Get', getDeleteParms, insertList, table[0], whereClause)
#print 'DELETE:'
#print deleteTemplate % (table[0] + '_Delete', table[0] + '_Delete', getDeleteParms, table[0], whereClause)
# Write out the INSERT stored proc
file = open('./test/' + table[0] + '_Insert', 'w')
file.write(insertTemplate % (table[0] + '_Insert', table[0] + '_Insert', insertUpdateParms, table[0], insertList, valuesList))
file.close()
# Write out the UPDATE stored proc
file = open('./test/' + table[0] + '_Update', 'w')
file.write(updateTemplate % (table[0] + '_Update', table[0] + '_Update', insertUpdateParms, table[0], updateList, whereClause))
file.close()
# Write out the GET stored proc
file = open('./test/' + table[0] + '_Get', 'w')
file.write(getTemplate % (table[0] + '_Get', table[0] + '_Get', getDeleteParms, insertList, table[0], whereClause))
file.close()
# Write out the DELETE stored proc
file = open('./test/' + table[0] + '_Delete', 'w')
file.write(deleteTemplate % (table[0] + '_Delete', table[0] + '_Delete', getDeleteParms, table[0], whereClause))
file.close()
return 0
if __name__ == '__main__':
generateSPs('<SERVER>', '<DATABASE>', '<USER>', '<PASSWD>')I found and fixed a bug with some misplaced parenthesis that forced the path to be made all lower-case. This was a bad thing if the path had some upper case letters in it!
#!/usr/bin/env python
# spgen.py
# Copyright 2008 Matt Runion <[email protected]>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import sys
import getopt
import os
import MySQLdb
# The INSERT template
insertTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
INSERT INTO %s (
%s
) VALUES (
%s
END$$
DELIMITER ;
# The UPDATE template
updateTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
UPDATE %s SET
%s
WHERE
%s;
END$$
DELIMITER ;
# The GET template
getTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
SELECT
%s
FROM %s
WHERE
%s;
END$$
DELIMITER ;
# The DELETE template
deleteTemplate = """
DELIMITER $$
DROP PROCEDURE IF EXISTS `%s`$$
CREATE PROCEDURE `%s` (%s)
BEGIN
DELETE FROM %s
WHERE
%s;
END$$
DELIMITER ;
def generateSPs(dbhost, dbname, dbuser, dbpasswd, outPath):
This method reads all the tables from the database and for each of them
generates the following stored routines:
<TableName>_Insert
<TableName>_Update
<TableName>_Get
<TableName>_Delete
# Open the database connection
print 'Connecting to database [%s] on host [%s]' % (dbname, dbhost)
dbConn = MySQLdb.connect(host=dbhost, user=dbuser, passwd=dbpasswd, db=dbname)
cur = dbConn.cursor()
# Get a list of all tables in the database
print 'Reading tables...'
cur.execute("SHOW TABLES FROM %s" % dbname)
tables = cur.fetchall()
for table in tables:
print 'Generating stored procs for table [%s]...' % table[0]
# Get a list of a columns in the current table
cur.execute("SHOW COLUMNS FROM %s" % table[0])
columns = cur.fetchall()
insertUpdateParms = ''
getDeleteParms = ''
whereClause = ''
insertList = ''
valuesList = ''
updateList = ''
for column in columns:
# Reset some variables
print ' %s -- %s [%s, %s, %s]' % (column[0], column[1], column[2], column[3], column[4])
# Append the columns to the input parms
if (len(insertUpdateParms) > 0):
insertUpdateParms += ',\n'
insertList += ',\n'
valuesList += ',\n'
if (len(updateList) > 0):
updateList += ',\n'
insertUpdateParms += '%sIN ' % column[0]
if ((column[1][0:3].lower() == 'var') or (column[1][0:3].lower() == 'cha')):
insertUpdateParms += '%s' % column[1]
elif (column[1][0:3].lower() == 'enu'):
insertUpdateParms += 'varchar(50)'
else:
insertUpdateParms += (column[1].split('('))[0]
insertList += column[0]
valuesList += '%sIN' % column[0]
# Generate the key parms that are used for the Get and Delete
# stored procs, and generate the values for the WHERE clause
# for the Update, Get and Delete stored procs
if (column[3].lower() == 'pri'):
if (len(getDeleteParms) > 0):
getDeleteParms += ',\n'
getDeleteParms += '%sIN ' % column[0]
if (column[1][0:3].lower() == 'var'):
getDeleteParms += '%s' % column[1]
else:
getDeleteParms += (column[1].split('('))[0]
if (len(whereClause) > 0):
whereClause += ' AND \n'
whereClause += '%s = %sIN' % (column[0], column[0])
else:
updateList += '%s = %sIN' % (column[0], column[0])
# Write out the INSERT stored proc
file = open(os.path.join(outPath,(table[0] + '_Insert.sql').lower()), 'w')
file.write(insertTemplate % (table[0] + '_Insert', table[0] + '_Insert', insertUpdateParms, table[0], insertList, valuesList))
file.close()
# Write out the UPDATE stored proc
file = open(os.path.join(outPath,(table[0] + '_Update.sql').lower()), 'w')
file.write(updateTemplate % (table[0] + '_Update', table[0] + '_Update', insertUpdateParms, table[0], updateList, whereClause))
file.close()
# Write out the GET stored proc
file = open(os.path.join(outPath,(table[0] + '_Get.sql').lower()), 'w')
file.write(getTemplate % (table[0] + '_Get', table[0] + '_Get', getDeleteParms, insertList, table[0], whereClause))
file.close()
# Write out the DELETE stored proc
file = open(os.path.join(outPath,(table[0] + '_Delete.sql').lower()), 'w')
file.write(deleteTemplate % (table[0] + '_Delete', table[0] + '_Delete', getDeleteParms, table[0], whereClause))
file.close()
return 0
def main(argv):
SPGen reads all the tables from the given database and for each of
those tables generates the following stored routines:
<TableName>_Insert
<TableName>_Update
<TableName>_Get
<TableName>_Delete
Command line arguments are:
-?, --help: Help
-o, --outputpath: File output path
-h, --host: Database host/server
-d, --database: Database name
-u, --user: Database user
-p, --password Database password
# Set defaults...
outputPath = os.getcwd()
host = 'localhost'
database = ''
user = ''
password = ''
# See what command line options we have
try:
opts, args = getopt.getopt(argv[1:], '?o:h:d:u:p:', ['help', 'outputpath=', 'host=', 'database=', 'user=', 'password='])
except getopt.GetoptError:
print main.__doc__
sys.exit(2)
for opt, arg in opts:
if opt in ['-?', '--help']:
print main.__doc__
sys.exit()
elif opt in ['-o', '--outputpath']:
outputPath = arg
elif opt in ['-h', '--host']:
host = arg
elif opt in ['-d', '--database']:
database = arg
elif opt in ['-u', '--user']:
user = arg
elif opt in ['-p', '--password']:
password = arg
generateSPs(dbhost=host, dbname=database, dbuser=user, dbpasswd=password, outPath=outputPath)
if __name__ == '__main__':
main(sys.argv)
Last edited by mrunion (2008-11-20 19:33:37) -
Python script in dasylab using single input multiple output
Hello
For a project, I would like to use the python scripting module of dasylab 13. I got it to work for simple functions such as y=f(x), where i have one input and one output.
The next step in order to get to where i want to be with my script is using a single input and generating two outputs.
I defined it in the "predefined settings" that pops up first. The module created looked as it should, having one input and two outputs. However, when I wanted to edit the script (and double clicked the module) the module went back to having one input and one output.
I searched the help and found the section "channel assignment constants". There describe the various constants, which should have been set in predefined settings. In my case it is CR_1_2.
It also states to setup the meta data in the SetupFifo tab.
Now here is my problem: How should i change the SetupFifo tab?
I tried the command:
self.SetChannelRelation(channel_no, Ly.CR_1_2)
Unfotunately this didn't work, which doesn't supprise me, as I made this command up, based on the examples in the help file on the SetupFifo tab. Those are, however, for SetChannelFlags and SetChannelType, which I don't think I need yet...
Has anyone experienced a similar problem? I also installed a trial version on another computer to check if it works there (it doesn't).
Or does someone know a method to find out how to be able to change inputs and outputs the way i want?
Every help will be greatly appreciated.
Sincerely, JarnoYou do not need to set the channel relation for "simple" channel relation like 1:2, 2:1, etc.
Just set the relation you want in the configration dialog that open when you drop a script module into to worksheet.
The channel relation and their python constants have nothing to do with the amount of inputs and outputs of a script module.
The channel relation tells the "DASYLab core" how to guide meta data (channel names, units, etc) through a module.
In function "DlgInit" you have to tell DASYLab how many inputs and outputs your module should have.
Your module should have 2 outputs for each input: this combination of input and outputs is called a "channel".
Because one channel has 2 outputs, the module can have max. 8 channels only.
The dialog with the channelbar "thinks" in channels, but DASYLab "thinks" in connectors (connectors are inputs/outputs).
So, you are responsible to translate "channels" in "connectors" and vice versa
In DlgInit you can ask DASYLab about the amount of inputs and outputs.
self.NumInChannel <-- amout of connectors on modules left side
self.NumOutChannel <-- amount of connectors on the right side
self.DlgNumChannels <-- amount of activated channels in the dialog (something between 1 and DlgMaxChannels)
Your module's channels have 1 input, 2 outputs each, so you can write either
self.DlgNumChannels = self.NumOutChannel / 2
or
self.DlgNumChannels = self.NumInChannel
If the module has 3 input and 6 outputs, the dialog will get 3 channels.
In DlgOk you need to translate the amount of channels into the correct amount of connectors (inputs/outputs):
For "one channel = 1 input + 2 outputs" this is:
self.SetConnectors( self.DlgNumChannels, self.DlgNumChannels * 2 )
DlgInit
self.DlgNumChannels = self.NumInChannel
# or: self.DlgNumChannels = self.NumOutChannel / 2
self.DlgMaxChannels = 8 # or Ly.MAX_CHANNELS/2
DlgOk
self.SetConnectors( self.DlgNumChannels, self.DlgNumChannels * 2 )
M.Sc. Holger Wons | measX GmbH&Co. KG, Mönchengladbach, Germany | DASYLab, DIAdem, LabView --- Support, Projects, Training | Platinum National Instrument Alliance Partner | www.measx.com -
Creating a PLSQL script to parse structured XML with repeated tags
Hi, I'm trying to parse an xml feed but the way it's structured makes it difficult to pull out the values. (see example) Would anyone be able to recommend a solution or some ideas as to how to get around this?
SAMPLE XML:<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header>
</env:Header>
<env:Body>
<ns3:commandResponse xmlns:ns2="http://test.com/2011/Generic/schema" xmlns:ns3="http://test.com/2011/Generic">
<return>
<ns2:return>success</ns2:return>
<ns2:Command>issues</ns2:Command>
<ns2:WorkItems>
<ns2:Id>216141</ns2:Id>
<ns2:ModelType>Issue</ns2:ModelType>
<ns2:DisplayId>216141</ns2:DisplayId>
<ns2:Field>
<ns2:Name>Type</ns2:Name>
<ns2:Value>
<ns2:Item>
<ns2:Id>Dev Task</ns2:Id>
<ns2:ModelType>Type</ns2:ModelType>
<ns2:DisplayId>Dev Task</ns2:DisplayId>
</ns2:Item>
</ns2:Value>
</ns2:Field>
<ns2:Field>
<ns2:Name>ID</ns2:Name>
<ns2:Value>
<ns2:int>216141</ns2:int>
</ns2:Value>
</ns2:Field>
<ns2:Field>
<ns2:Name>Reason</ns2:Name>
<ns2:Value>
<ns2:string>Integrating</ns2:string>
</ns2:Value>
</ns2:Field>
<ns2:Field>
<ns2:Name>Dev Task Component</ns2:Name>
<ns2:Value>
<ns2:string>Java Tools</ns2:string>
</ns2:Value>
</ns2:Field>
<ns2:Field>
<ns2:Name>Created Date</ns2:Name>
<ns2:Value>
<ns2:datetime>2009-08-10T15:52:39.000-04:00</ns2:datetime>
</ns2:Value>
</ns2:Field>
<ns2:Field>
<ns2:Name>Date Closed</ns2:Name>
<ns2:Value/>
</ns2:Field>
<ns2:Field>
<ns2:Name>Modified Date</ns2:Name>
<ns2:Value>
<ns2:datetime>2011-03-04T12:57:05.000-05:00</ns2:datetime>
</ns2:Value>
</ns2:Field>
</ns2:WorkItems>
</return>
</ns3:commandResponse>
</env:Body>
</env:Envelope>This is just a sample with just one WorkItem, but there would be much more, N number of items with 9 fields per item. (Not all of the fields were put in the sample, and some can have null values)
I only need to pull the content from /ns2:WorkItems/ns2:Field/ns2:Value/ns2:Item/ns2:Id for the first field and the /ns2:value/* tag of all the other fields. Then put this in a table where each row is a workitem and the fields are the columns (create table workitems (Type,ID,Reason,Dev Task Component,Created Date, Date Closed, Modified Date) --all the fields should be varchar2 except the dates)
What I've been trying so far seems rather brute force by running a nested loop to go through every item and field and then an IF case for each field 1,2,...9 which would insert the value into a table.
At the moment I'm using something like below to pull a single value
path1 = '//ns2:WorkItems[1]/ns2:Field[1]/ns2:Value[1]/ns2:Item[1]/ns2:Id[1]';
nameserve = 'xmlns:ns2="http://test.com/2011/Generic/schema"';
extractvalue(xmltype(src_clob),path1,nameserve);I'm not entirely sure if I would be able to substitute the [1]'s with [' || nitem || '] where nitem is loop number to do something like:
for nitem in 1..itemcount
loop
FOR nfield in 1..9
loop
if nfield=1 then
path1 := '//ns2:WorkItems[' || nitem || ']/ns2:Field[' || nfield || ']/ns2:Value[1]/ns2:Item[1]/ns2:Id';
fieldvalue := extractvalue(xmltype(src_clob),path1,nameserve);';
else
path2 := '//ns2:WorkItems[' || nitem || ']/ns2:Field[' || nfield || ']/ns2:Value[1]/*[1]';
fieldvalue := extractvalue(xmltype(src_clob),path2,nameserve);';
end if;
end loop;
end loop;The problem with the above script is how do I insert this fieldvalue into different columns on a table without using an IF case for each field.
I was wondering if there is simpler way to put each field into a different column and loop through every workitem. I looked into dynamically naming variables but I don't think plsql supports that.
Any help/advice is appreciated,
Thanks!
Edited by: 843508 on Mar 10, 2011 1:56 PM
Edited by: 843508 on Mar 10, 2011 1:57 PM
Edited by: 843508 on Mar 10, 2011 2:01 PMIf it were me, I wouldn't use PL/SQL to try and process XML, but would use SQL's XMLTABLE functionality e.g.
SQL> ed
Wrote file afiedt.buf
1 WITH t as (select XMLTYPE('
2 <RECSET xmlns:aa="http://www.w3.org">
3 <aa:REC>
4 <aa:COUNTRY>1</aa:COUNTRY>
5 <aa:POINT>1800</aa:POINT>
6 <aa:USER_INFO>
7 <aa:USER_ID>1</aa:USER_ID>
8 <aa:TARGET>28</aa:TARGET>
9 <aa:STATE>6</aa:STATE>
10 <aa:TASK>12</aa:TASK>
11 </aa:USER_INFO>
12 <aa:USER_INFO>
13 <aa:USER_ID>5</aa:USER_ID>
14 <aa:TARGET>19</aa:TARGET>
15 <aa:STATE>1</aa:STATE>
16 <aa:TASK>90</aa:TASK>
17 </aa:USER_INFO>
18 </aa:REC>
19 <aa:REC>
20 <aa:COUNTRY>2</aa:COUNTRY>
21 <aa:POINT>2400</aa:POINT>
22 <aa:USER_INFO>
23 <aa:USER_ID>3</aa:USER_ID>
24 <aa:TARGET>14</aa:TARGET>
25 <aa:STATE>7</aa:STATE>
26 <aa:TASK>5</aa:TASK>
27 </aa:USER_INFO>
28 </aa:REC>
29 </RECSET>') as xml from dual)
30 -- END OF TEST DATA
31 select x.country, x.point, y.user_id, y.target, y.state, y.task
32 from t
33 ,XMLTABLE(XMLNAMESPACES('http://www.w3.org' as "aa"),
34 '/RECSET/aa:REC'
35 PASSING t.xml
36 COLUMNS country NUMBER PATH '/aa:REC/aa:COUNTRY'
37 ,point NUMBER PATH '/aa:REC/aa:POINT'
38 ,user_info XMLTYPE PATH '/aa:REC/*'
39 ) x
40 ,XMLTABLE(XMLNAMESPACES('http://www.w3.org' as "aa"),
41 '/aa:USER_INFO'
42 PASSING x.user_info
43 COLUMNS user_id NUMBER PATH '/aa:USER_INFO/aa:USER_ID'
44 ,target NUMBER PATH '/aa:USER_INFO/aa:TARGET'
45 ,state NUMBER PATH '/aa:USER_INFO/aa:STATE'
46 ,task NUMBER PATH '/aa:USER_INFO/aa:TASK'
47* ) y
SQL> /
COUNTRY POINT USER_ID TARGET STATE TASK
1 1800 1 28 6 12
1 1800 5 19 1 90
2 2400 3 14 7 5p.s. XML questions are better suited in the XML DB forum:
XML DB FAQ -
I have finally upgraded to Lion and I am slowly finding out small things that are making me go crazy.
Before on Snow Leopard, I could just double click a python script and it would open up and do it's thing.
Now, it won't even open. When you go into the info panel I can't find the Python Launcher option. It only
gives me other apps such as Sublime Text, Text Wranger etc. How do I change this back to how it was
behaving in snow leapard, without going through Terminal.
Does anyone know why my numbers pad on the keyboard doesn't work anymore?nevermind
-
Iwl3945: no scan results with 'iwlist scan'
hello!
i have a little problem. i successfully use the iwl3945 wifi driver. i can connect with the arch network scripts.
but i cannot scan anymore with the iwlist tool. it tells me that there are no scan results.
anyone else with this problem? how can i fix it?
thx, mfg iggyI find this strange too.
[marc@~] iwlist wlan0 scan
wlan0 No scan results
[marc@~] su -
Password:
[root@~] iwlist wlan0 scan
wlan0 Scan completed :
Cell 01 - Address: 00:19:5B:0B:21:16
ESSID:"scram"
Mode:Master
Channel:9
Frequency:2.452 GHz (Channel 9)
Quality=88/100 Signal level=-45 dBm Noise level=-84 dBm
Encryption key:on
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s
48 Mb/s; 54 Mb/s
Extra:tsf=000007f9c4876b63
[root@~] -
Open a python script containing bundle... problems!
I'm not sure how to extract the bundle from this python script. I won't go into much detail, but you can look at this example project I found that can replace InstallerPluginSample with python to create a bundle file. Your help will be much appreciated
http://pyobjc.sourceforge.net/examples/pyobjc-framework-InstallerPlugins/Install erPluginSample/index.htmlthis is the script I got closest with - I know its something to do with breaking those two commands up but i just dont know how to do it
on run {input, parameters}
tell application "Terminal"
activate
if (the (count of the window) = 0) or ¬
(the busy of window 1 = true) then
tell application "System Events"
keystroke "n" using command down
end tell
end if
do script "cd /Users/behole/Desktop/FlickrUpload/" & "python uploadr.py -d" in window 1
end tell
return input
end run
this is the error I get in terminal after I run it
Last login: Mon Jul 23 15:37:17 on ttys000
be-holes-MacBook-Pro:~ behole$ cd /Users/behole/Desktop/FlickrUpload/python uploadr.py -d
-bash: cd: /Users/behole/Desktop/FlickrUpload/python: No such file or directory
be-holes-MacBook-Pro:~ behole$ -
Scripting modifications to LDAP inside Python script
Hi all,
I have written Python scripts to create redundant print services on two OS X Server 10.6 machines running print services for al hundred or so macs in computer labs. The Mac printing (which printers appear to users) is managed via MCX w/OD. Essentially how they work is this:
*script periodically tests socket connectivity on primary server IPP/LPR ports
*on failure script does command to start Print Service on backup print server
*script then does command on OD LDAP to import mcx settings for backup print server to all applicable managed clients
The commands are done with "Popen" so they are shell commands. To modify the LDAP directory, I would use the Popen equivalent of "/usr/bin/dscl -u <diradmin user> -P <diradmin pwd> /LDAPv3/127.0.0.1 -mcximport /<managed client path> <path to mcx settings>"
It would be much nicer to not have the auth info hardcoded into the script. I've tried logging in to a shell on the server under the diradmin credentials and running the python script, but get permission denied when trying to modify LDAP. I also tried giving a test user account "full" privileges in WGM to modify directory and running script logged into a shell as this user, with the same failure.
I may be missing something totally obvious, but I am coming up blank..
Is there any way to script modification to the LDAP directory without supplying credentials in the script?Hi all,
I have written Python scripts to create redundant print services on two OS X Server 10.6 machines running print services for al hundred or so macs in computer labs. The Mac printing (which printers appear to users) is managed via MCX w/OD. Essentially how they work is this:
*script periodically tests socket connectivity on primary server IPP/LPR ports
*on failure script does command to start Print Service on backup print server
*script then does command on OD LDAP to import mcx settings for backup print server to all applicable managed clients
The commands are done with "Popen" so they are shell commands. To modify the LDAP directory, I would use the Popen equivalent of "/usr/bin/dscl -u <diradmin user> -P <diradmin pwd> /LDAPv3/127.0.0.1 -mcximport /<managed client path> <path to mcx settings>"
It would be much nicer to not have the auth info hardcoded into the script. I've tried logging in to a shell on the server under the diradmin credentials and running the python script, but get permission denied when trying to modify LDAP. I also tried giving a test user account "full" privileges in WGM to modify directory and running script logged into a shell as this user, with the same failure.
I may be missing something totally obvious, but I am coming up blank..
Is there any way to script modification to the LDAP directory without supplying credentials in the script? -
Is there a way I can call a python script from within a Robohelp script?
Hi,
I want to integrate an external python script into the current extendscript I use in RoboHelp 10. Is there a way to do that?
Thanks,
LaurenYou can use the command line to call any kind of external application.
Personally, I use the following function to create bat files to do such
work.
I've taken these functions from my free RH Extendscript library -
http://www.wvanweelden.eu/product/robohelp-extendscript-library
function ExecuteBatchFile(command, waitforbatch) {
if(string_isEmpty(command))
return false;
if(!waitforbatch) {
if(waitforbatch != false) {
waitforbatch = true;
var path = Folder.appData.fsName + '/';
var batFileName = 'ExtendScriptBatchFile';
var batFileExtension = '.bat';
var batFile = new File(pathbatFileNamebatFileExtension);
if(batFile.exists) {
var i = 0;
while(batFile.exists) {
i++;
batFile = new File(pathbatFileNamei+batFileExtension);
command+= "\ndel /F /Q \"" + batFile.fsName + "\"";
writeFile(batFile, command, false);
if(!isFile(batFile, true))
return false;
batFile.execute();
/* Wait on batch file execution if needed */
if(waitforbatch) {
while(batFile.exists) {
msg(".");
$.sleep(100);
return true;
function writeFile(file, szOutput, encoding) {
var szFilePath = file.fsName;
if(!encoding || encoding == true) {
encoding = "UTF-8";
var fileObj = new File(szFilePath);
fileObj.encoding = encoding;
fileObj.open("w");
fileObj.write(szOutput);
fileObj.close();
Kind regards,
Willam -
I keep getting no as an answer unfortunately but I'm asking here. I'm not talking about omino's graphics plugin, I need to use this in more of a scripting scope. As far as I've seen, his plugin does graphics related stuff.
Run a Python script in what fashion? Just looking to launch it from within AE? You could use the execute() method for a File object to just launch it with it's default app. You might also launch via command line with the system.callSystem() method. If you're on MAC, you might even be able to intigrate it into an AppleScript to launch it as well. As far as launching/using Python directly within AE, this hasn't been possible since "Useful Things" went away.
-
Call a python script from perl file
This is my first post and am not sure if this is the right forum to post this query. If this is not the right forum, pls redirect me to the appropriate forum.
Query :
I have a python script which was created through WLS console's recording feature. I have to call this python script from a perl script (dte topo block).
Any pointers towards how this can be achieved ?
Thanks,
MadhusudanI am using inline python to execute python statements directly from the perl script. However, i get below error :
[maddeshp@slc01auw forDTE]$ perl -c intro.pl
Can't find string terminator "END_OF_PYTHON_CODE" anywhere before EOF at intro.pl line 2.
Has anyone run into this problem ? Any suggestions on fixing this ?
Thanks,
Madhusudan
Maybe you are looking for
-
Im trying to view my account on itunes as I have had quite a few amounts going out? But I cant see exactly what the payments are for. How do I view this?
-
I like to use the keyboard shortcut ¨command-L¨ to go to the current song that's playing in Itunes. Since upgrading to itunes 12 this shortcut command only brings the download window to front. Does anyone else experiencing this problem? Does anyone h
-
InApp Purchase not being funded
Right, so I decided to purchase a £15 gift card, activated it and bought some credits for an App. Funnily enough the company can quickly take my funds, however, can't fund me the credits which I bought. I have not recieved an e-mail of confirmation f
-
Why mac os does not recognize arabic fonts
in mac pro using lion os does not support arabic fonts except one font and not like mac photoshop w` recognize a lot of arabic fonts why and how to solve
-
OS Migrations from Winwows 2003 to 2008 Server
Hello Experts, I wanted to know if we can Migrate our OS From windows 2003 to Windows 2008 without System copy/Database Refresh. Here is what we have currently installed in Windows 2003 Server OS: Windows 2003 Server SID: ECP Database Oracle: 10g SA