<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PRINT HEAD &#187; Software</title>
	<atom:link href="http://cyberelk.net/tim/category/techie-stuff/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://cyberelk.net/tim</link>
	<description></description>
	<lastBuildDate>Tue, 08 Dec 2009 17:28:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fedora Updates can be revised</title>
		<link>http://cyberelk.net/tim/2009/12/08/fedora-updates-can-be-revised/</link>
		<comments>http://cyberelk.net/tim/2009/12/08/fedora-updates-can-be-revised/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 14:54:50 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[fedora]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=815</guid>
		<description><![CDATA[Fedora package developers very often submit a test update for a package, get some feedback on it, then submit another test update incorporating further fixes.  This resets the &#8220;karma&#8221; back to zero, as well as making search results for packages in the Fedora Update system very cluttered.
Did you know that you can edit an existing [...]]]></description>
			<content:encoded><![CDATA[<p>Fedora package developers very often submit a test update for a package, get some feedback on it, then submit <em>another</em> test update incorporating further fixes.  This resets the &#8220;karma&#8221; back to zero, as well as making search results for packages in the Fedora Update system very cluttered.</p>
<p>Did you know that you can edit an existing test update?  Doing this keeps the list of fixed bugs, keeps any user comments about the update, and keeps the karma from previous testing.</p>
<p><img class="aligncenter size-full wp-image-817" title="Edit" src="http://cyberelk.net/tim/wp-content/uploads/2009/12/edit.png" alt="Edit" width="261" height="36" /></p>
<p>After clicking Edit, make your changes but be sure to choose Testing or Stable for the Request field.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/12/08/fedora-updates-can-be-revised/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mapping encrypted volume groups to disk partitions</title>
		<link>http://cyberelk.net/tim/2009/11/09/mapping-encrypted-volume-groups-to-disk-partitions/</link>
		<comments>http://cyberelk.net/tim/2009/11/09/mapping-encrypted-volume-groups-to-disk-partitions/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 15:45:18 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[lvm]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=811</guid>
		<description><![CDATA[I&#8217;m about to try installing a Fedora 12 test image onto the spare disk partition in this computer, but it&#8217;s taken me a while to work out which partition actually is spare.  The reason: most of my filesystems are in logical volumes on LUKS-encrypted devices.
So, for my own reference as much as anything else, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m about to try installing a Fedora 12 test image onto the spare disk partition in this computer, but it&#8217;s taken me a while to work out which partition actually is spare.  The reason: most of my filesystems are in logical volumes on LUKS-encrypted devices.</p>
<p>So, for my own reference as much as anything else, here is how to map an encrypted logical volume back to an actual disk partition.</p>
<p><span id="more-811"></span></p>
<p>Take a look at the mounted devices with &#8220;mount&#8221;.  In my case, I can see that <tt>/dev/mapper/vg_worm01-LogVol00</tt> is mounted at the filesystem root <tt>/</tt>.  This logical volume belongs to a volume group <tt>vg_worm01</tt> (it&#8217;s right there in the name).</p>
<p>Next, take a look at which physical volumes are collected into this volume group using &#8220;pvdisplay&#8221;.  For me, that&#8217;s just one: <tt>/dev/dm-1</tt>.</p>
<p>Finally, &#8220;cryptsetup status /dev/dm-1&#8243; says which actual device underlies the whole lot: <tt>/dev/sda3</tt>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/11/09/mapping-encrypted-volume-groups-to-disk-partitions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HPLIP 3.9.10</title>
		<link>http://cyberelk.net/tim/2009/11/04/hplip-3-9-10/</link>
		<comments>http://cyberelk.net/tim/2009/11/04/hplip-3-9-10/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 17:19:00 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=804</guid>
		<description><![CDATA[To head off the question before I&#8217;m asked it: no, HPLIP 3.9.10 will not be in Fedora 12.  We will stick with 3.9.8.
The 3.9.10 release contains a completely re-written print filter, 27 thousand lines of new code, all of it written by HP with no outside review.  There is no public source code repository for [...]]]></description>
			<content:encoded><![CDATA[<p>To head off the question before I&#8217;m asked it: no, HPLIP 3.9.10 will not be in Fedora 12.  We will stick with 3.9.8.</p>
<p>The 3.9.10 release contains a completely re-written print filter, 27 thousand lines of new code, all of it written by HP with no outside review.  There is no public source code repository for HPLIP so 3.9.10 is the first time this code has seen the light of day.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/11/04/hplip-3-9-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CUPS cancelled jobs showing up in the queue</title>
		<link>http://cyberelk.net/tim/2009/10/16/cups-cancelled-jobs-showing-up-in-the-queue/</link>
		<comments>http://cyberelk.net/tim/2009/10/16/cups-cancelled-jobs-showing-up-in-the-queue/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 12:02:36 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[fedora]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=801</guid>
		<description><![CDATA[The newest stable branch of CUPS, 1.4, has a different job cancellation behaviour (hey, two words in a row spelt differently in American English!) than 1.3 did.  If you have cancelled a job but it still appears in the job queue, this might explain why.

The lpstat -o command shows jobs that are in the CUPS [...]]]></description>
			<content:encoded><![CDATA[<p>The newest stable branch of CUPS, 1.4, has a different job cancellation behaviour (hey, two words in a row spelt differently in American English!) than 1.3 did.  If you have cancelled a job but it still appears in the job queue, this might explain why.</p>
<p><span id="more-801"></span></p>
<p>The <tt>lpstat -o</tt> command shows jobs that are in the CUPS scheduler&#8217;s &#8216;active jobs<br />
list&#8217;.  The CUPS web interface also uses this list when displaying the job queue; so does the system-config-printer job viewer.</p>
<p>In CUPS 1.3 and earlier you should never see cancelled jobs in queue.</p>
<p>In CUPS 1.4 the only time you should see cancelled jobs in the queue is when those jobs have been cancelled but one or more filters or backends have not yet finished.</p>
<p>When a job is cancelled, each process in the job pipeline is sent a SIGTERM signal.  If there is no signal handler, this kills the process there and then.</p>
<p>However, the CUPS backends ignore that signal and just wait for the filters to finish sending data.  The reason for this is that some devices may require sort of reset code to be sent in order to be back in their &#8216;normal&#8217; state.</p>
<p>In contrast to CUPS 1.3, in 1.4 a job is not immediately removed from the active jobs list at the time it is cancelled.  This is in order to implement a job kill delay: after the configurable &#8216;JobKillDelay&#8217; (default is 300 seconds), any remaining filters or backends associated with cancelled jobs on the active jobs list are sent SIGKILL, and the job is removed from the active jobs list.</p>
<p>CUPS 1.4 is available in Fedora 11.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/10/16/cups-cancelled-jobs-showing-up-in-the-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PolicyKit and printing</title>
		<link>http://cyberelk.net/tim/2009/08/11/policykit-and-printing/</link>
		<comments>http://cyberelk.net/tim/2009/08/11/policykit-and-printing/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 10:59:34 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[PolicyKit]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[system-config-printer]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=785</guid>
		<description><![CDATA[The latest release of Fedora allows more flexibility with configuring print queues and managing print jobs.  This is because it is now able to use PolicyKit to do these things, which means you get to choose when and whether users should be prompted for authentication when performing administration tasks on printers or jobs.  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://cyberelk.net/tim/wp-content/uploads/2009/08/gtk-dialog-authentication-100.png"><img class="alignleft size-full wp-image-794" title="gtk-dialog-authentication-100" src="http://cyberelk.net/tim/wp-content/uploads/2009/08/gtk-dialog-authentication-100.png" alt="gtk-dialog-authentication-100" width="100" height="100" /></a>The <a href="http://docs.fedoraproject.org/release-notes/f11/">latest release of Fedora</a> allows more flexibility with configuring print queues and managing print jobs.  This is because it is now able to use <a href="http://www.freedesktop.org/wiki/Software/PolicyKit">PolicyKit</a> to do these things, which means you get to choose when and whether users should be prompted for authentication when performing administration tasks on printers or jobs.  The implementation is slightly tricky, so I&#8217;ll explain the details.</p>
<p><span id="more-785"></span></p>
<p>Before PolicyKit awareness was added there was already adjustable policy controlling IPP operations.  This &#8216;CUPS policy&#8217; mechanism is provided by the CUPS scheduler, <code>cupsd</code>, and its configuration is in the file <code>/etc/cups/cupsd.conf</code>.  This controls which IP addresses are allowed to access various HTTP locations corresponding to the CUPS configuration actions (such as <code>http://cups-server:631/admin</code>), and which IP address, users, groups, and classes of users can carry out the various IPP operations such as cancelling jobs.  It also specifies whether and how users must authenticate themselves.</p>
<p>This CUPS policy is great for managing CUPS servers remotely but is not consistent with the method used by the rest of the desktop environment, PolicyKit.  Although the CUPS policy can be adjusted using a fairly easy to use list of check-boxes (available in both the CUPS web interface and via <a href="http://cyberelk.net/tim/software/system-config-printer/">System→Administration→Printing</a>), it is not fine-grained enough to be as useful as PolicyKit can be.  The CUPS policy itself is very fine-grained, but this power is only unleashed by editing configuration files.</p>
<p>With PolicyKit the policy can be adjusted easily using a graphical tool, to make it easier to perform certain tasks for those needing to do so.  The intention is for <a href="http://spins.fedoraproject.org/">Fedora &#8220;spins&#8221;</a> to have appropriate default policies depending on their target audience, so that a desktop spin might allow the active console user to perform all administration tasks without asking for authentication for example.</p>
<p>We have two types of policy then, CUPS policy and PolicyKit policy, for controlling print administration tasks.  The CUPS policy in Fedora is unmodified from the upstream CUPS releases, and is fairly restrictive.  The default PolicyKit policy for printing administration in Fedora is also fairly restrictive, and the overall policy is only as restrictive as the most relaxed of the two.</p>
<p>The implementation consists of a package called <code>cups-pk-helper</code> (created by <a href="http://www.vuntz.net/journal/">Vincent Untz</a>) which provides the D-Bus system service which is the mechanism for the policy &#8212; it performs the administration tasks on behalf of its clients by talking to the CUPS scheduler using IPP.  It runs as root so the default CUPS policy allows it to perform all administration tasks.  It can authenticate itself as root by connecting over a UNIX domain socket (CUPS will use <a href="http://cyberelk.net/tim/2007/03/08/cups-unix-domain-sockets-authentication/">peer credentials</a> to discover the requesting user) or, if that is not possible, by proving that it can read a certificate file only readable by root.</p>
<p>At present the only client for this system service is the printer configuration tool accessible from System→Administration→Printing.  The CUPS web interface and command line tools only use IPP directly.</p>
<p>How fine-grained is the policy?  Here are the defined operations:</p>
<ul>
<li>Set a printer as system default printer</li>
<li>Enable/disable a printer</li>
<li>Add/remove/edit a local printer</li>
<li>Add/remove/edit a remote printer</li>
<li>Add/remove/edit a class</li>
<li>Get/set server settings</li>
<li>Restart/cancel/edit a job you own</li>
<li>Restart/cancel/edit a job owned by another user</li>
<li>Get the list of available devices (available in Fedora 11 <a href="https://bugzilla.redhat.com/show_bug.cgi?id=516713">soon</a>)</li>
</ul>
<p>For each of these operations, the policy depends on who is attempting to carry out the operation:</p>
<ul>
<li>Someone on the active console</li>
<li>Someone on the console but inactive</li>
<li>Anyone else</li>
</ul>
<p>For each of these groups of users, the policy can be that they are disallowed altogether, that they are allowed without authentication, or that they require authentication either as themselves or with the root password.  If authentication is required it can be:</p>
<ul>
<li>Required every time</li>
<li>Required once but not needed for the rest of the time the configuration program is running</li>
<li>Required once per session</li>
<li>Required once and not again</li>
</ul>
<p>Here is a screenshot of the program used for editing this policy, accessible from System→Preferences→Authorizations:</p>
<p><a href="http://cyberelk.net/tim/wp-content/uploads/2009/08/polkit.png"><img class="alignnone size-full wp-image-791" title="Editing policy" src="http://cyberelk.net/tim/wp-content/uploads/2009/08/polkit.png" alt="Editing policy" width="450" height="406" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/08/11/policykit-and-printing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D-Bus system services for print queues</title>
		<link>http://cyberelk.net/tim/2009/07/26/d-bus-system-services-for-print-queues/</link>
		<comments>http://cyberelk.net/tim/2009/07/26/d-bus-system-services-for-print-queues/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 17:42:35 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[dbus]]></category>
		<category><![CDATA[printers]]></category>
		<category><![CDATA[system-config-printer]]></category>
		<category><![CDATA[udev]]></category>
		<category><![CDATA[usb]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=779</guid>
		<description><![CDATA[Further to the recent work on replacing hal-cups-utils, I&#8217;ve now split out the parts that use CUPS into a D-Bus system service.  This allows udev to simply call the D-Bus methods and let the activated service deal with the potentially time-consuming bits.  It also makes it a bit easier to get the SELinux [...]]]></description>
			<content:encoded><![CDATA[<p>Further to the recent work on replacing hal-cups-utils, I&#8217;ve now split out the parts that use CUPS into a D-Bus system service.  This allows udev to simply call the D-Bus methods and let the activated service deal with the potentially time-consuming bits.  It also makes it a bit easier to get the SELinux security labelling right.</p>
<p>The interface is simple:</p>
<p>bus <code>com.redhat.PrinterConfig</code><br />
object <code>/com/redhat/PrinterConfig</code><br />
interface <code>com.redhat.PrinterConfig</code></p>
<p><code>UsbPrinterAdd (STRING devpath, STRING deviceid)<br />
UsbPrinterRemove (STRING devpath)</code></p>
<p>Next step: a D-Bus service for finding an appropriate PPD file for a given IEEE 1284 Device ID.  This would allow the <code>PrinterConfig</code> implementation to avoid running a Python helper script to actually add the queue.  The same goes for bluetooth devices.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/07/26/d-bus-system-services-for-print-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Re-writing hal-cups-utils to avoid hal</title>
		<link>http://cyberelk.net/tim/2009/07/20/re-writing-hal-cups-utils-to-avoid-hal/</link>
		<comments>http://cyberelk.net/tim/2009/07/20/re-writing-hal-cups-utils-to-avoid-hal/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 18:06:12 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[system-config-printer]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=774</guid>
		<description><![CDATA[The program that adds printer queues when a USB printer is connected is hal-cups-utils.  It is a simple program that hooks into hal, the hardware abstraction layer, and adds/enables/disables CUPS queues as necessary.
As hal will be going away shortly &#8212; that, and the fact that hal-cups-utils doesn&#8217;t really work very well &#8212; I have [...]]]></description>
			<content:encoded><![CDATA[<p>The program that adds printer queues when a USB printer is connected is hal-cups-utils.  It is a simple program that hooks into <a href="http://www.freedesktop.org/wiki/Software/hal">hal</a>, the hardware abstraction layer, and adds/enables/disables CUPS queues as necessary.</p>
<p>As hal will be going away shortly &#8212; that, and the fact that hal-cups-utils doesn&#8217;t really work very well &#8212; I have had a go at re-writing it as a udev rule over the last few days.</p>
<p><span id="more-774"></span></p>
<p>The way it works is as follows.  We have two ACTION==&#8221;add&#8221; triggers: one for the usb_device and one for the USB class driver (usblp) device.  We need both of them because:</p>
<ul>
<li>at least one, and soon two, of the CUPS backends will most likely unload the usblp module if it is loaded, in order to use libusb.  This means that the usb_device is the only reliable object we can track to see when printers have been disconnected.</li>
<li>if the usblp module is already loaded, libusb won&#8217;t work because usblp holds open the raw device.</li>
<li>the usblp module may be blacklisted altogether, as most printer device users use libusb now.</li>
</ul>
<p>We have a single ACTION==&#8221;remove&#8221; trigger for the usb_device.</p>
<p>On &#8220;add&#8221; we obtain the Device ID by fair means or foul, depending on whether the usblp module is loaded.  We match this against devices reported by CUPS using the device-id attribute, and keep a note of this mapping of USB devpath to device URIs.  Note that if we fail to contact CUPS we just exit &#8212; the idea is that the CUPS initscript will replay the udev events after cupsd is started.</p>
<p>Next, we examine the existing CUPS queues to see if any of them use any of the device URIs associated with our device.  If so, and they are disabled, and we&#8217;d disabled them, we enable them.</p>
<p>If no queues match, we invoke udev-add-printer to create a queue.</p>
<p>On &#8220;remove&#8221; we look up the list of device URIs associated with our USB devpath, then examine the existing CUPS queues to see if any of them use it.  If so they are disabled.</p>
<p>A walk in the park.</p>
<p>(I know which I&#8217;d prefer.)</p>
<p>The code is in the udev branch of system-config-printer.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/07/20/re-writing-hal-cups-utils-to-avoid-hal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Profiling Python</title>
		<link>http://cyberelk.net/tim/2009/07/16/profiling-python/</link>
		<comments>http://cyberelk.net/tim/2009/07/16/profiling-python/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 10:03:07 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[system-config-printer]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=751</guid>
		<description><![CDATA[Yesterday I spent a little bit of time improving the speed of adding a new printer using system-config-printer.  The main problem was that several bugs had conspired to make it search for all printer drivers three times instead of just once (oops).  After fixing that I tried profiling it to see what was [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I spent a little bit of time improving the speed of adding a new printer using <a href="http://cyberelk.net/tim/software/system-config-printer/">system-config-printer</a>.  The main problem was that several bugs had conspired to make it search for all printer drivers three times instead of just once (oops).  After fixing that I tried profiling it to see what was taking the most time.</p>
<p><span id="more-751"></span></p>
<p>I used the <code>cProfile/pstats</code> modules to do this.  It&#8217;s quite easy to do.  I replace the part where my program says:</p>
<pre>gtk.main()</pre>
<p>with:</p>
<pre>import cProfile
cProfile.run("gtk.main()", "profile.out")</pre>
<p>After running the program I used an interactive Python shell to display the profiling statistics, ordered by cumulative time taken in each function:</p>
<pre>$ python
>>> import pstats
>>> p=pstats.Stats("profile.out")
>>> p.strip_dirs().sort_stats("cumulativ").print_stats()
Wed Jul 15 17:57:41 2009    profile.out

         1962150 function calls (1959323 primitive calls) in 21.377 CPU seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   21.377   21.377 &lt;string&gt;:1(&lt;module&gt;)
        1    3.968    3.968   21.377   21.377 {gtk._gtk.main}
        1    0.000    0.000   12.303   12.303 system-config-printer.py:4109(on_btnNPForward_clicked)
        1    0.000    0.000   12.303   12.303 system-config-printer.py:4112(nextNPTab)
        1    0.000    0.000    6.549    6.549 system-config-printer.py:4052(loadPPDs)
        1    0.001    0.001    6.549    6.549 system-config-printer.py:4018(fetchPPDs)
       60    6.515    0.109    6.515    0.109 {time.sleep}
        1    0.000    0.000    4.631    4.631 system-config-printer.py:3360(on_new_printer_activate)
        1    0.000    0.000    4.539    4.539 system-config-printer.py:3720(init)
        1    0.000    0.000    4.342    4.342 ppds.py:475(getPPDNameFromDeviceID)
        1    0.024    0.024    4.279    4.279 system-config-printer.py:4850(fillDeviceTab)
        1    0.000    0.000    4.208    4.208 system-config-printer.py:4538(fetchDevices)
        1    0.000    0.000    4.096    4.096 cupshelpers.py:511(getDevices)
        1    0.000    0.000    4.096    4.096 authconn.py:184(<lambda>)
        1    2.069    2.069    4.096    4.096 authconn.py:186(_authloop)
        4    0.083    0.021    3.985    0.996 ppds.py:816(_init_makes)
    11133    0.753    0.000    3.933    0.000 ppds.py:34(ppdMakeModelSplit)
   202792    0.463    0.000    2.056    0.000 re.py:144(sub)
...</pre>
<p>As system-config-printer is an interactive graphical application, a lot of time was spent waiting for me to react to the interface.  The functions at the top of the list are there for that reason.  However, <code>getPPDNameFromDeviceID</code> is not interactive yet is taking an enormous amount of time: over four seconds!  This time does not include the time taken to retrieve the list of available PPDs from CUPS (see <code>loadPPDs</code>), but is entirely spent on processing that data and trying to find a matching driver for the printer I was using.</p>
<p>In a lot of cases it would not take as long as this.  In this instance, however, there is no exact match for my printer so it has to perform a lot more processing in order to find a &#8220;close&#8221; match.  Part of that processing involves splitting the (often messy) ppd-make-and-model attributes for the PPDs into manufacturer names and model names.</p>
<p>The reason this was taking so long is apparent from the profiling, in conjunction with reading the code.  It is the fact that regular expressions are used extensively to process the ppd-make-and-model attributes.  This is confirmed by running <code>p.print_callers(20)</code>:</p>
<pre>
...
Function                  was called by...
                              ncalls  tottime  cumtime
...
re.py:144(sub)            <-  202791    0.463    2.055  ppds.py:34(ppdMakeModelSplit)
...
</pre>
<p>One way of making this more efficient would be to "compile" the regular expressions once, then execute the compiled expressions on each call.  However, by using simple string operations instead of regular expressions in that function, the cumulative time used by <code>ppdMakeModelSplit</code> was reduced from 3.93s to 0.98s.</p>
<p>The lesson: regular expressions are expensive!</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/07/16/profiling-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating ChangeLog files from commit logs</title>
		<link>http://cyberelk.net/tim/2009/06/25/generating-changelog-files-from-commit-logs/</link>
		<comments>http://cyberelk.net/tim/2009/06/25/generating-changelog-files-from-commit-logs/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 10:44:41 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[system-config-printer]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=730</guid>
		<description><![CDATA[I love git, but I also loved ChangeLog files and git is not so good at merging them.  For a while I played around with gnulib&#8217;s git-merge-changelog which made merges really easy.  It worked fairly well, but now I&#8217;m bored of documenting my changes twice, both in the ChangeLog file and in the [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://git-scm.com/">git</a>, but I also loved <a href="http://www.gnu.org/prep/standards/html_node/Change-Logs.html">ChangeLog</a> files and git is not so good at merging them.  For a while I played around with <a href="http://www.gnu.org/software/gnulib/">gnulib</a>&#8217;s <a href="http://cyberelk.net/tim/2008/05/29/git-merge-changelog/">git-merge-changelog</a> which made merges really easy.  It worked fairly well, but now I&#8217;m bored of documenting my changes twice, both in the ChangeLog file and in the git commit log.</p>
<p>The coreutils project has been creating its ChangeLog file from the git commit logs for a little while now, and I decided to take a look at how that&#8217;s done.  Now, at last, <a href="http://cyberelk.net/tim/software/system-config-printer/">system-config-printer</a> can do that too.  Here is how it works.</p>
<p><span id="more-730"></span></p>
<p>Step 1 happened a while ago, and that was to modify the style of my git commit log entries.  I now write a single line at the top giving a summary of the overall change (as before), so that I get nice output from tools that want to abbreviate the commit log to one line.  Then I leave a blank line, and below that my ChangeLog-style entry with no indentation.</p>
<p>Firstly, the gitlog-to-changelog script from gnulib has been added to the repository.  This is the build tool Jim Meyering wrote which does all the work.</p>
<p>Next, I renamed the ChangeLog file &#8220;ChangeLog-OLD&#8221;, because I&#8217;d like to keep that history around without any alterations.</p>
<p>I use automake in system-config-printer, but it gets upset if there is no ChangeLog file.  To pacify it I modified the &#8220;bootstrap&#8221; script to create an empty ChangeLog file.  I added &#8220;/ChangeLog&#8221; to the .gitignore file so that I don&#8217;t get continually told about this dummy file not being under revision control.</p>
<p>Finally, to generate the ChangeLog file from git commit logs whenever a new release is built I added a &#8220;dist-hook&#8221; rule to the automake file, getting it to run the gitlog-to-changelog script.</p>
<p>These changes were made on the 1.1.x branch.  The older 1.0.x branch still has a normal ChangeLog file in the source repository, and when changes are made on that branch and merged into 1.1.x the ChangeLog entries get merged into ChangeLog-OLD automatically (git is fantastic for merging changes across renamed files).</p>
<p>The actual changes are <a href="http://git.fedorahosted.org/git/?p=system-config-printer.git;a=commitdiff;h=f9e28d0717a1ed408487f03bba8b20bb2f40e90e">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/06/25/generating-changelog-files-from-commit-logs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>One PDF implementation down (many to go)</title>
		<link>http://cyberelk.net/tim/2009/06/22/one-pdf-implementation-down-many-to-go/</link>
		<comments>http://cyberelk.net/tim/2009/06/22/one-pdf-implementation-down-many-to-go/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 11:53:21 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[poppler]]></category>

		<guid isPermaLink="false">http://cyberelk.net/tim/?p=719</guid>
		<description><![CDATA[Recently I updated CUPS in Fedora 9 and 10 to version 1.3.10.  One big change in CUPS 1.3.10 is in the filter for converting PDF documents to PostScript: it has been completely reimplemented.  This sounds like a lot of work but in fact it is now a very simple wrapper program.

Prior to 1.3.10 [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I updated CUPS in Fedora 9 and 10 to version 1.3.10.  One big change in CUPS 1.3.10 is in the filter for converting PDF documents to PostScript: it has been completely reimplemented.  This sounds like a lot of work but in fact it is now a very simple wrapper program.</p>
<p><span id="more-719"></span></p>
<p>Prior to 1.3.10 it was based on Xpdf but with some changes to make it work as a CUPS filter.  This meant that every PDF security vulnerability had to be fixed separately in both Xpdf and in CUPS&#8217;s pdftops program, not to mention all the other PDF implementations (ghostscript, <a href="http://poppler.freedesktop.org/">poppler</a>, etc).</p>
<p>The new CUPS PDF filter just runs the pdftops program that comes with poppler, or alternatively ghostscript depending on the CUPS build configuration (in Fedora we use poppler for this).</p>
<p>In future if any new PDF security vulnerabilities are discovered, CUPS in Fedora will not need to be patched for them.  Yay!</p>
]]></content:encoded>
			<wfw:commentRss>http://cyberelk.net/tim/2009/06/22/one-pdf-implementation-down-many-to-go/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
