<html>
<STYLE type="text/css">
H1 {border-width: 1; border: solid}
</STYLE>
<title>Scripting Column as of $Date: 2004/08/20 $</title>
<h1><center>Monthly Scripting Column for April</center></h1>
<table border=0 width="100%">
<tr><td width="70%">
<p>Greetings!
This continues a series of bulletins, in which we introduce
one of the scripts that will be in a future release.
<td>
<table border=1 width="100%">
<tr><td><i><font color="blue">Tip: don't like the output? Use 'p4 -G' output as input to your Python script, and format the data (or graph it) to your liking.</font></i>
</table>
</tr>
</table>
<hr>
<h2>Today's script</h2>
<p><b>Leverage off other work.</b>
We hear this often, and say it in this column a lot, too.
The most error-prone programming I encounter is data validation code.
That's the stuff that
reads input, validates it, etc. Any chance I get to use code
that someone else has already created (and tested), I'll take.
<p>
To that end, there's a facility available to Python programmers
for retrieving that data from a Perforce query without parsing
through formatted output.
This option, "p4 -G", retrieves Perforce data to be read
by a Python program:
<pre> p4 <font color="red">-G</font> clients | python program.py </pre>
Today's example retrieves that output using the
Python library routine, <em>os.popen</em>.
<p>
The "-G" option, which went between <em>p4</em> and <em>clients</em>,
sets the output option to a binary format.
That format is called "marshal", and is a representation
of a Python variable or object.
<p>
You can read such output with this routine written in Python,
which runs a Perforce command and
returns the results of the 'p4' command. The results are
easy for the Python programmer to use: an array of 'dict'
objects.
<pre>
import os
import marshal
def runp4cmd(p4cmd):
""" Return the output from the Perforce command,
and assume that the user put the '-G' in the options
to get us marshall output. We always return an array
for the results."""
fd = os.popen(p4cmd, 'r')
results = []
while 1:
try:
d = marshal.load(fd)
results.append(d)
except EOFError:
break
fd.close()
return results <em># end of runp4cmd</em>
clientList = runp4cmd('p4 -G clients')
for c in clientList:
print c['client']
</pre>
<p>
In the following example, there's a reference to the Options field.
(We normally think of it as a list of strings, since that's how the
client spec is formatted when we run 'p4 client.')
The first thing is to burst it into an array,
<em>optionList</em>,
so that we can search it easily.
<hr>
<pre>
import marshal,os, pprint,sys
from readp4marshal import runp4cmd
# Task: determine which client specs have the option 'nocompress'set.
#
# status: tested on Win/2000 using python 2.0
# num of calls to 'p4': 1
clientList = runp4cmd("p4 -G clients")
for c in clientList:
optionList = c['Options'].split(' ')
for o in optionList:
if o == 'compress':
print "%s: compression of data (default)" % c['client']
if o == 'nocompress':
print "%s: *no* compression of data" % c['client']
</pre>
<hr>
<center><b>findnocompress.py</b></center>
<hr>
<small><p>Note: all the programs shown in these columns have been written four times: in Perl, in P4Perl, in Python, and in P4Ruby. Look into the Perforce example database for the other versions.</small>
<br>
<i><small>$Id: //guest/jeff_bowles/scripts/0430python.html#1 $</small>
<br>© 2004 Perforce Corporation, Inc.</small></i>
</html>
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 4420 | Jeff Bowles |
adding the beginnings of example "columns" for scripting examples. |