<?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>Alunduil&#039;s Hosting &#187; python</title>
	<atom:link href="http://www.alunduil.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alunduil.com</link>
	<description>Gentoo Hackery and Other Fun ...</description>
	<lastBuildDate>Sun, 01 May 2011 22:00:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Small Interpreters Using Python</title>
		<link>http://www.alunduil.com/2010/12/15/small-interpreters-using-python/</link>
		<comments>http://www.alunduil.com/2010/12/15/small-interpreters-using-python/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 01:59:41 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bison]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[grammar]]></category>
		<category><![CDATA[lemon]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[pyparsing]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[readline]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tiny basic]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=254</guid>
		<description><![CDATA[Introduction I know this doesn&#8217;t come up nearly as often as other topics but writing an interpreter (a.k.a. a compiler) can be a very useful concept depending on what exactly you need to do with the input to your program. For example, what if we had a fairly strict data store but we for some <a href='http://www.alunduil.com/2010/12/15/small-interpreters-using-python/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>I know this doesn&#8217;t come up nearly as often as other topics but writing an interpreter (a.k.a. a compiler) can be a very useful concept depending on what exactly you need to do with the input to your program.  For example, what if we had a fairly strict data store but we for some reason wanted to access it using something like SQL?  We&#8217;d have to parse the SQL statements and then find a way to mogrify it until we had something that would allow us to get the data we wanted.  There is an easier way involving a little parsing theory.  For the purposes of this discussion I&#8217;m assuming you are at least somewhat familiar with <a href="http://en.wikipedia.org/wiki/Context-free_grammar">Context Free Grammars</a>.</p>
<h1>Creating the Grammar</h1>
<p>The first step to creating a parser (especially when using a parser generator) is to find or craft a definition for the grammar.  The grammar we&#8217;ll use as an example is the expression grammar from tiny basic.  This simple grammar is safe for LR or LL parsing (which is important if you look at a common definition of a language like SQL).</p>
<h2>Tiny Basic Expression Grammar</h2>
<pre>expression ::= (+|-|ε) term ((+|-) term)*
term ::= factor ((*|/) factor)*
factor ::= number | (expression)</pre>
<h1>Enter pyparsing</h1>
<p>To create a very simple and extensible LL parser I&#8217;ve recently stumbled upon <a href="http://pyparsing.wikispaces.com/">pyparsing</a>.  This simple four production grammar expands to the following pyparsing implementation:</p>
<p>[sourcecode language="python" wraplines="false"]<br />
expr = Forward()<br />
factor = ( Word(nums) | Group(Suppress(&#8216;(&#8216;) + expr + Suppress(&#8216;)&#8217;)) )<br />
term = Group(factor + ZeroOrMore((Literal(&#8216;*&#8217;)|Literal(&#8216;/&#8217;)) + factor))<br />
expr &lt;&lt; Group(Optional(Literal(&#8216;-&#8217;)|Literal(&#8216;+&#8217;)) + term + ZeroOrMore((Literal(&#8216;-&#8217;)|Literal(&#8216;+&#8217;)) + term))<br />
[/sourcecode]</p>
<p>This allows us to turn sentences such as &#8216;<span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: 12px; line-height: 18px; white-space: pre;">5+5*6/3-(47+56)*34</span>&#8216; into an easy to work with list such as: &#8216;<span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: 12px; line-height: 18px; white-space: pre;">[[['5'], &#8216;+&#8217;, ['5', '*', '6', '/', '3'], &#8216;-&#8217;, [[[['47'], &#8216;+&#8217;, ['56']]], &#8216;*&#8217;, &#8217;34&#8242;]]]</span>&#8216;.  There are probably improvements that could be made to this parser so that it auto-collapses expressions and other fun handlers but for the purposes of a simple grammar this will suffice.</p>
<p>Calling the grammar after defining it is a very simple process: <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: 12px; line-height: 18px; white-space: pre;">`expr.parseString(&#8217;5+5*6/3-(47+56)*34&#8242;)`</span>.</p>
<h1>Testing Parsers an Easier Way</h1>
<p>Sure unit testing should be done (and parsers lend themselves to unit tests very well) but there&#8217;s something satisfying about seeing your sentences get parsed out in real time.  The obvious answer is, &#8220;create a mini-shell like environment.&#8221;  Python also makes this process extremely simple and only requires a few lines of code to get a basically functional shell for your parser (complete with history):</p>
<p>[sourcecode language="python" wraplines="false"]<br />
import rlcompleter<br />
import readline<br />
import so</p>
<p>if not os.access(&quot;.history&quot;, os.F_OK): open(&quot;.history&quot;, &quot;w&quot;).close()<br />
readline.read_history_file(&quot;.history&quot;)<br />
buffer = &quot;&quot;</p>
<p>while True:<br />
    try: line = raw_input(pycolorize.light_blue(&quot;BASIC$ &quot;))<br />
    except EOFError:<br />
        readline.write_history_file(&quot;.history&quot;)<br />
        print<br />
        break</p>
<p>    if line.lower() == &quot;exit&quot; or line.lower() == &quot;quit&quot;:<br />
        readline.write_history_file(&quot;.history&quot;)<br />
        break</p>
<p>    buffer += line<br />
    result = ACTION_ON_BUFFER<br />
    buffer = &quot;&quot;<br />
[/sourcecode]</p>
<h1>Putting It Together</h1>
<p>The complete script for reference purposes:</p>
<p>[sourcecode language="python" wraplines="false"]<br />
import rlcompleter<br />
import readline<br />
import os</p>
<p>from pyparsing import *<br />
import pprint</p>
<p>if not os.access(&quot;.history&quot;, os.F_OK): open(&quot;.history&quot;, &quot;w&quot;).close()<br />
readline.read_history_file(&quot;.history&quot;)</p>
<p>try:<br />
    import pycolorize<br />
except:<br />
    sys.path.append(os.path.join(os.path.dirname(__file__), &quot;vendor&quot;, &quot;pycolorize&quot;))<br />
    import pycolorize</p>
<p>class ExpressionParser(object):<br />
    def __init__(self):<br />
    self._expr = Forward()<br />
    factor = ( Word(nums) | Group(Suppress(&#8216;(&#8216;) + self._expr + Suppress(&#8216;)&#8217;)) )<br />
    term = Group(factor + ZeroOrMore((Literal(&#8216;*&#8217;)|Literal(&#8216;/&#8217;)) + factor))<br />
    self._expr &lt;&lt; Group(Optional(Literal(&#8216;-&#8217;)|Literal(&#8216;+&#8217;)) + term + ZeroOrMore((Literal(&#8216;-&#8217;)|Literal(&#8216;+&#8217;)) + term))</p>
<p>    def _calculate(self, l):<br />
        while any([ isinstance(x, list) for x in l]):<br />
            for n,i in enumerate(l):<br />
                if isinstance(i, list): l[n] = self._calculate(i)<br />
        return str(eval(&quot; &quot;.join(l)))</p>
<p>    def __call__(self, string):<br />
        return self._calculate(self._expr.parseString(string).asList())</p>
<p>buffer = &quot;&quot;</p>
<p>print pycolorize.green(&quot;Enter your SQL commands to tokenize:&quot;)<br />
print pycolorize.green(&quot;Enter a blank line to exit.&quot;)</p>
<p>while True:<br />
    try: line = raw_input(pycolorize.light_blue(&quot;BASIC$ &quot;))<br />
    except EOFError:<br />
        readline.write_history_file(&quot;.history&quot;)<br />
        print<br />
        break</p>
<p>    if line.lower() == &quot;exit&quot; or line.lower() == &quot;quit&quot;:<br />
        readline.write_history_file(&quot;.history&quot;)<br />
        break</p>
<p>    buffer += line<br />
    result = None<br />
    try: result = ExpressionParser()(buffer)<br />
    except ParseBaseException, e:<br />
        buffer = &quot;&quot;<br />
        pycolorize.error(e.line)<br />
        pycolorize.error(&quot; &quot;*(e.col &#8211; 1) + &quot;^&quot;)<br />
        pycolorize.error(str(e))<br />
        continue<br />
    pycolorize.status(&quot;Result: %s&quot;, result)<br />
    buffer = &quot;&quot;<br />
[/sourcecode]</p>
<h1>Conclusion</h1>
<p>Writing LL parsers is a breeze with pyparsing but it must be kept in mind that any grammar that has any left recursion will cause errors that may take some time to find or remove.  Other parser generators (for C and C++) include bison and lemon.  These parser generators are LR parser generators.</p>
<p>By coupling the parser with a small CLI quick checks on new features to the grammar (and by extension the parser) can be a breeze.  Putting this all together with unit tests and proper grammar analysis can lead to a well written and extensible language to be used for whatever purpose you may have in mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2010/12/15/small-interpreters-using-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Plugins (Dynamic Modules)</title>
		<link>http://www.alunduil.com/2010/12/03/python-plugins-dynamic-modules/</link>
		<comments>http://www.alunduil.com/2010/12/03/python-plugins-dynamic-modules/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 21:54:04 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=251</guid>
		<description><![CDATA[Introduction Sometimes dynamically loaded modules (plugins or extensions) are pretty convenient to provide extensible functionality from your applications. For example, you need to provide a command that provides known data sources to subcommands but want the subcommands to be easily written and added even after the application has been finalized. We could do this with <a href='http://www.alunduil.com/2010/12/03/python-plugins-dynamic-modules/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>Sometimes dynamically loaded modules (plugins or extensions) are pretty convenient to provide extensible functionality from your applications.  For example, you need to provide a command that provides known data sources to subcommands but want the subcommands to be easily written and added even after the application has been finalized.  We could do this with a simply proper modular design but it seems more natural to allow for the subcommands to be defined elsewhere with a standard interface to allow for extensible behavior even after the initial application development cycle.</p>
<h1>The Problem</h1>
<p>How do we find and then load and then run code that we didn&#8217;t necessarily write?</p>
<p>The first step is fairly obvious we simply ask (via a parameter, config option, or other method) where the code that should be loaded is located.  Once we have that the other steps are much easier.  In more detail, we need to know a location for code that follows our plugin API resides.  To do this we can use the following code (where d is the directory with our plugins):</p>
<p>[sourcecode language="python"]<br />
sys.path.append(d)<br />
files = itertools.chain(*[ [ os.path.join(x[0], fs) for fs in x[2] ] for x in os.walk(d) ] )<br />
plugins = [ f.split('/')[-1].split(&#8216;.&#8217;)[0] for f in files if f.endswith(&#8216;.py&#8217;) ]<br />
modules = [ __import__(p, globals(), locals(), [], -1) for p in plugins ]</p>
<p>for p,m in zip(plugins,modules):<br />
matches = [ x for x in m.__dict__.keys() if x.lower() == p ]<br />
if len(matches) == 1: # and issubclass(m.__dict__[matches[0]], CorkyCommand):<br />
self._commands.append(m.__dict__[matches[0]]())<br />
[/sourcecode]</p>
<h2>Break Down</h2>
<ol>
<li>Add our directory to the python module path so we can simply load them by name</li>
<li>Get a list of the files in this directory</li>
<li>Filter this down to the names of the python files to find the Class that we need to create an instance of</li>
<li>Import the modules as module objects we can manipulate</li>
<li>Loop through the correlated list of plugin names and module objects</li>
<li>Look for an object in the module dictionary that matches the name of the file (case insensitive)</li>
<li>Find a match we then add an instantiated object of the class we found</li>
</ol>
<p>Quite a bit is going in this short snippet of code but the important thing is it takes a directory path and creates a list of instantiated plugin objects we can use just like any other object variable.  Once we have the objects it&#8217;s simply a matter of calling functions on them: `self._commands[n].method()`.</p>
<h1>Conclusion</h1>
<p>Getting a modular design can be daunting and making that modular design as dynamic as possible can be even more daunting but the modern languages (this technique but not syntax works with ruby as well) make this process much easier than the compiled languages (More to come on that later I hope).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2010/12/03/python-plugins-dynamic-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pclean, a new /etc/portage/package.* cleaner</title>
		<link>http://www.alunduil.com/2010/11/07/pclean-a-new-etcportagepackage-cleaner/</link>
		<comments>http://www.alunduil.com/2010/11/07/pclean-a-new-etcportagepackage-cleaner/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 15:53:34 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Linux Guides]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[layman]]></category>
		<category><![CDATA[overlay]]></category>
		<category><![CDATA[pclean]]></category>
		<category><![CDATA[portage]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=245</guid>
		<description><![CDATA[I&#8217;ve often gotten frustrated with my /etc/portage/package.* files when they become massive and full of crud that I don&#8217;t even have installed any longer. Because of this I have crafted a simple little utility to clean out packages that are no longer installed and use flags that are no longer valid from these files. This <a href='http://www.alunduil.com/2010/11/07/pclean-a-new-etcportagepackage-cleaner/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve often gotten frustrated with my /etc/portage/package.* files when they become massive and full of crud that I don&#8217;t even have installed any longer.  Because of this I have crafted a simple little utility to clean out packages that are no longer installed and use flags that are no longer valid from these files.  This should help trim the cruft from the Gentoo configuration.</p>
<p>The utility, <a href="http://www.alunduil.com/programs/pclean/">pclean</a>, does all of this and only has one major problem (so far) before I shall call it good enough for a 1.0 release.  If you would like to try this little utility; it&#8217;s available in <a href="http://www.alunduil.com/alunduil-overlay/">my overlay</a> and if you notice any odd behavior please report it to <a href="https://bugzilla.alunduil.com/buglist.cgi?cmdtype=runnamed&amp;namedcmd=Pclean">my bugzilla</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2010/11/07/pclean-a-new-etcportagepackage-cleaner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Holland on Gentoo</title>
		<link>http://www.alunduil.com/2010/08/01/holland-on-gentoo/</link>
		<comments>http://www.alunduil.com/2010/08/01/holland-on-gentoo/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 18:32:37 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Linux Guides]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[directory]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[holland]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[lvm]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[portage]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=167</guid>
		<description><![CDATA[Introduction There is a new king of backups in town, holland. This little framework written in Python allows one to easily backup anything that might need to be converted to a more flat file style before being backed up. Right now there is support for mysql, sqlite, and postgresql but with a little finesse it <a href='http://www.alunduil.com/2010/08/01/holland-on-gentoo/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>There is a new king of backups in town, <a href="http://hollandbackup.org/">holland</a>.  This little framework written in Python allows one to easily backup anything that might need to be converted to a more flat file style before being backed up.  Right now there is support for mysql, sqlite, and postgresql but with a little finesse it could potentially support directories as well as databases.  This would make not only mysql backups a breeze but LDAP as well.</p>
<h1>Progress Update</h1>
<p>I have added a preliminary set of ebuilds to my overlay (which could use some code review if anyone is interested) that allows holland to easily be installed on Gentoo systems.  So easy in fact that all it takes is `emerge holland`.</p>
<p>It accepts a set of use flags to bring in the &#8220;providers&#8221; you want to be able to backup for and makes sure that those packages are installed on the system.</p>
<h2>Examples</h2>
<p>The holland ebuilds have three providers right now:</p>
<ul>
<li>mysql</li>
<li>postgresql</li>
<li>sqlite</li>
</ul>
<p>You can install any of these three you want in any combination; it doesn&#8217;t care.  It will default to installing the mysql but can easily be told not to by placing -mysql in the use flags for holland. <a href="http://blog.flameeyes.eu/">Diego Pettenò — Flameeyes</a> mentioned to me that in EAPI 4 we&#8217;ll get the cool option of being able to specify one of a set of use flags must be set without forcing the choice but until then we have this slick solution.</p>
<p>There is also lvm support for snapshotting off the database directory before grabbing the database and a myriad of other features I haven&#8217;t had a chance to explore yet.</p>
<p>To perform a rudimentary backup after installing holland simply run `holland bk`.  This will read the configurations in `/etc/holland` and backup the databases it finds.</p>
<h1>Conclusion</h1>
<p>The new kid on the block, holland, will make backups of complex databases and directories a breeze.  Simply change that cronjob from using mysqldump to calling holland and you&#8217;re finished.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2010/08/01/holland-on-gentoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Disabling&#8221; KScreenSaver via DBUS</title>
		<link>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus/</link>
		<comments>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 05:36:32 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Linux Guides]]></category>
		<category><![CDATA[dbus]]></category>
		<category><![CDATA[kde]]></category>
		<category><![CDATA[kde 4]]></category>
		<category><![CDATA[kscreensaver]]></category>
		<category><![CDATA[powerdevil]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stop screensaver]]></category>
		<category><![CDATA[stop_kscreensaver]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=59</guid>
		<description><![CDATA[KDE 4 has some major improvements over older versions, but it also seems to have gone backwards in places. The new libraries probably contribute to this and are absolutely the way to go. A nice ability that I&#8217;ve been looking for in powerdevil (the new power manager in KDE 4) is how to have the <a href='http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>KDE 4 has some major improvements over older versions, but it also seems to have gone backwards in places.  The new libraries probably contribute to this and are absolutely the way to go.  A nice ability that I&#8217;ve been looking for in powerdevil (the new power manager in KDE 4) is how to have the screensaver &#8220;disable&#8221; when entering presentation mode.  This is behavior that I know I expected but found to my dismay partway through a presentation that the screensaver still kicked in.</p>
<p>After looking around for ways to &#8220;fix&#8221; this problem, I finally found some interesting information in the form of the DBUS interface provided by the screensaver in KDE.  Using qdbusviewer I was able to find an API for the screensaver that can be invoked at any point and from anywhere (assuming that you&#8217;re part of the session).  Using this new ammunition for more Google searching, I found that I could write a daemon in python that would keep the screensaver from displaying while it was turned on.</p>
<p>The result of this work can be found in my subversion repository as [stop_kscreensaver.py](http://www.alunduil.com/svn/stop_kscreensaver/trunk/stop_kscreensaver.py).  This script only has 3 parameters and is very easy to use.  When starting the daemon you simply pass a time between activity simulations (by setting this just shorter than the timeout for your screensaver activation it is much more efficient) and if desired a different log level.  To stop the daemon you simply pass the kill parameter which reads the PID from a standard file and makes sure the daemon dies.</p>
<p>The timing parameter for this script is fairly functional in that you can pass the time in with various units and the conversion will be taken into account.  For example, one could pass a time of 2h32.1m94.34s.  Why anyone would is beyond me, but I figured with regular expressions it might be easy to do.  If no units are passed the script assumes that the number passed was in seconds.  As always if any bugs are found please e-mail me, [Alex Brandt](mailto:alunduil@alunduil.com) with a description of the problem (or if you&#8217;re ambitious a patch file would be appreciated).</p>
<p>Now the important part.  How do we get this to work with powerdevil?  That&#8217;s the easiest part of all with powerdevil&#8217;s execute this script when switching to this profile feature.  We simply save the script somewhere, make it executable (chmod 755), and then set the path (or browse to it) in the powerdevil configuration interface.</p>
<p>Once that is in place you can switch to the profile you set the daemon up to start in and the screensaver although active will not start up until you switch profiles again.  This lets you watch that movie you wanted to just like our favorite comic [XKCD](http://xkcd.com/196/) tells us about.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&quot;Disabling&quot; KScreenSaver via DBUS</title>
		<link>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus-2/</link>
		<comments>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus-2/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 05:36:32 +0000</pubDate>
		<dc:creator>Alex Brandt</dc:creator>
				<category><![CDATA[Linux Guides]]></category>
		<category><![CDATA[dbus]]></category>
		<category><![CDATA[kde]]></category>
		<category><![CDATA[kde 4]]></category>
		<category><![CDATA[kscreensaver]]></category>
		<category><![CDATA[powerdevil]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stop screensaver]]></category>
		<category><![CDATA[stop_kscreensaver]]></category>

		<guid isPermaLink="false">http://www.alunduil.com/?p=59</guid>
		<description><![CDATA[KDE 4 has some major improvements over older versions, but it also seems to have gone backwards in places. The new libraries probably contribute to this and are absolutely the way to go. A nice ability that I&#8217;ve been looking for in powerdevil (the new power manager in KDE 4) is how to have the <a href='http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus-2/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>KDE 4 has some major improvements over older versions, but it also seems to have gone backwards in places.  The new libraries probably contribute to this and are absolutely the way to go.  A nice ability that I&#8217;ve been looking for in powerdevil (the new power manager in KDE 4) is how to have the screensaver &#8220;disable&#8221; when entering presentation mode.  This is behavior that I know I expected but found, to my dismay, partway through a presentation that the screensaver still kicked in.</p>
<p>After looking around for ways to &#8220;fix&#8221; this problem, I finally found some interesting information in the form of the DBUS interface provided by the screensaver in KDE.  Using qdbusviewer I was able to find an API for the screensaver that can be invoked at any point and from anywhere (assuming that you&#8217;re part of the session).  Using this new ammunition for more Google searching, I found that I could write a daemon in python that would keep the screensaver from displaying while it was turned on.</p>
<p>The result of this work can be found in my subversion repository as <a href="http://www.alunduil.com/svn/stop_kscreensaver/trunk/stop_kscreensaver.py">stop_kscreensaver.py</a>.  This script only has 3 parameters and is very easy to use.  When starting the daemon you simply pass a time between activity simulations (by setting this just shorter than the timeout for your screensaver activation it is much more efficient) and if desired a different log level.  To stop the daemon you simply pass the kill parameter which reads the PID from a standard file and makes sure the daemon dies.</p>
<p>The timing parameter for this script is fairly functional in that you can pass the time in with various units and the conversion will be taken into account.  For example, one could pass a time of 2h32.1m94.34s.  Why anyone would is beyond me, but hey I figured with regular expressions it might be easy to do.  If no units are passed the script assumes that the number passed was in seconds.  As always if any bugs are found please e-mail me, [Alex Brandt](mailto:alunduil@alunduil.com) with a description of the problem (or if you&#8217;re ambitious a patch file would be appreciated).</p>
<p>Now the important part.  How do we get this to work with powerdevil?  That&#8217;s the easiest part of all with powerdevil&#8217;s execute this script when switching to this profile feature.  We simply save the script somewhere, make it executable (chmod 755), and then set the path (or browse to it) in the powerdevil configuration interface.</p>
<p>Once that is in place you can switch to the profile you set the daemon up to start in and the screensaver although active will not start up until you switch profiles again.  This lets you watch that movie you wanted to just like our favorite comic <a href="http://xkcd.com/196/">XKCD</a> tells us about.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alunduil.com/2009/07/22/disabling-kscreensaver-via-dbus-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached (User agent is rejected)
Database Caching 4/18 queries in 0.021 seconds using memcached
Object Caching 527/568 objects using memcached

Served from: www.alunduil.com @ 2012-02-06 09:25:51 -->
