<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Drew Perttula</name>
  </author>
  <id>tag:drewp.quickwitretort.com,2005-02-13:16:18:07-NewsBruiser-weblog</id>
  <link href="http://drewp.quickwitretort.com/syndicate/weblog" type="application/atom+xml" rel="self"/>
  <link href="http://drewp.quickwitretort.com/" type="text/html" rel="alternate"/>
  <title>drewp</title>
  <updated>2012-02-02T21:26:48.395777-08:00</updated>
  <entry>
    <id>http://drewp.quickwitretort.com/2012/02/02/0</id>
    <title>Using zc.recipe.cmmi with zc.recipe.egg</title>
    <published>2012-02-02T21:26:48.395777-08:00</published>
    <updated>2012-02-02T21:26:48.395777-08:00</updated>
    <link href="http://drewp.quickwitretort.com/2012/02/02/0" type="text/html" rel="alternate"/>
    <content type="html">&lt;p&gt;&lt;a href="https://github.com/gawel/gp.recipe.node"&gt;gp.recipe.node&lt;/a&gt; is nice, and it depends on &lt;a href="http://pypi.python.org/pypi/zc.recipe.cmmi"&gt;zc.recipe.cmmi&lt;/a&gt; and &lt;a href="http://pypi.python.org/pypi/zc.recipe.egg/1.3.2"&gt;zc.recipe.egg&lt;/a&gt; at the same time. If those two got installed into dirs like these:&lt;/p&gt;&#13;
&lt;p&gt;eggs/zc.recipe.egg-1.3.2-py2.7.egg/zc/recipe/&lt;/p&gt;&#13;
&lt;p&gt;eggs/zc.recipe.cmmi-1.3.5-py2.7.egg/zc/recipe/&lt;/p&gt;&#13;
&lt;p&gt;. . you'll get an error like this:&lt;/p&gt;&#13;
&lt;p&gt;% bin/node&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "bin/node", line 17, in &amp;lt;module&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; import gp.recipe.node.script&lt;br /&gt;&amp;nbsp; File "eggs/gp.recipe.node-0.2-py2.7.egg/gp/recipe/node/__init__.py", line 5, in &amp;lt;module&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from zc.recipe.egg import Scripts&lt;br /&gt;ImportError: No module named egg&lt;/p&gt;&#13;
&lt;p&gt;A fix is to replace eggs/zc.recipe.cmmi-1.3.4-py2.7.egg/zc/recipe/__init__.py with these contents:&lt;/p&gt;&#13;
&lt;p&gt;__import__('pkg_resources').declare_namespace(__name__)&lt;br /&gt;import pkgutil&#13;
&lt;br /&gt;__path__ = pkgutil.extend_path(__path__, __name__)&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;p&gt;Next, I wish gp.recipe.node would run node in a way that replaces its own process, instead of running a child. Then &lt;a href="http://supervisord.org/"&gt;supervisord&lt;/a&gt; would have an easier time killing the node process.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>http://drewp.quickwitretort.com/2012/01/08/0</id>
    <title>How to run graphite 0.9.9 without installing any code</title>
    <published>2012-01-08T23:07:29.626119-08:00</published>
    <updated>2012-01-08T23:07:29.626119-08:00</updated>
    <link href="http://drewp.quickwitretort.com/2012/01/08/0" type="text/html" rel="alternate"/>
    <content type="html">&lt;p&gt;Here's how to start from a linux box with python 2.7 and virtualenv, and end up with a running graphite web server and data collector daemon (carbon-cache). I use supervisord and nginx as well, but you don't need exactly those to make the setup work.&lt;br /&gt;&lt;br /&gt;mkdir /new/dir&lt;/p&gt;&#13;
&lt;p&gt;cd /new/dir&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;h4&gt;Fetch software&lt;/h4&gt;&#13;
&lt;p&gt;virtualenv .&lt;br /&gt;&lt;br /&gt;bin/easy_install "gunicorn==0.13.4"&lt;br /&gt;bin/easy_install "Django==1.3.1"&lt;br /&gt;bin/easy_install "graphite_web==0.9.9"&lt;br /&gt;bin/easy_install "carbon==0.9.9"&lt;/p&gt;&#13;
&lt;p&gt;bin/easy_install "whisper==0.9.9"&lt;/p&gt;&#13;
&lt;p&gt;bin/easy_install http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz&lt;/p&gt;&#13;
&lt;h4&gt;Setup configs&lt;/h4&gt;&#13;
&lt;p&gt;cp ./lib/python2.7/site-packages/carbon-0.9.9-py2.7.egg/conf/carbon.conf.example ./carbon.conf&lt;br /&gt;echo "TIME_ZONE = 'America/Los_Angeles'" &amp;gt; local_settings.py&lt;br /&gt;ln -s ../../../../../local_settings.py ./lib/python2.7/site-packages/graphite_web-0.9.9-py2.7.egg/graphite/local_settings.py&lt;/p&gt;&#13;
&lt;p&gt;mkdir -p storage/log/webapp&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;h4&gt;Run this once to init a sqlite database&lt;br /&gt;&lt;/h4&gt;&#13;
&lt;p&gt;GRAPHITE_STORAGE_DIR=storage/ DJANGO_SETTINGS_MODULE=graphite.settings bin/django-admin.py syncdb&lt;br /&gt;&lt;br /&gt;It will say "you don't have any superusers defined. Would you like to create one now?" Say yes and put add minimal information. I'm not sure where this information ever shows up again.&lt;/p&gt;&#13;
&lt;h4&gt;Run these two daemons&lt;/h4&gt;&#13;
&lt;p&gt;GRAPHITE_CONF_DIR=. GRAPHITE_ROOT=. bin/carbon-cache.py --debug start&lt;br /&gt;&lt;br /&gt;GRAPHITE_STORAGE_DIR=storage/&#13;
 bin/gunicorn_django -b 0.0.0.0:9037 &#13;
./lib/python2.7/site-packages/graphite_web-0.9.9-py2.7.egg/graphite/settings.py&lt;br /&gt;&lt;br /&gt;Here's a config for supervisord that runs those lines:&lt;br /&gt;&lt;br /&gt;[program:graphite_carbon_2003]&lt;br /&gt;directory=/opt/graphite/0.9.9&lt;br /&gt;environment=GRAPHITE_CONF_DIR=.,GRAPHITE_ROOT=. &lt;br /&gt;command=/opt/graphite/0.9.9/bin/carbon-cache.py --debug start&lt;br /&gt;# --debug needed for fg mode, but now it logs every datapoint operation&lt;br /&gt;stdout_logfile=/dev/null&lt;br /&gt;&lt;br /&gt;[program:graphite_9037]&lt;br /&gt;directory=/opt/graphite/0.9.9&lt;br /&gt;environment=GRAPHITE_STORAGE_DIR=storage/&lt;br /&gt;command=/opt/graphite/0.9.9/bin/gunicorn_django&#13;
 -b 0.0.0.0:9037 &#13;
./lib/python2.7/site-packages/graphite_web-0.9.9-py2.7.egg/graphite/settings.py&lt;br /&gt;&lt;/p&gt;&#13;
&lt;h4&gt;Serve the web page&lt;/h4&gt;&#13;
&lt;p&gt;Set your web server to proxy http://something.example.com/ to localhost:9037. The graphite pages are full of /root addresses, so it's very hard to serve graphite from anywhere but the top of its own (sub)domain. Serve http://something.example.com/content from the static files at ./lib/python2.7/site-packages/graphite_web-0.9.9-py2.7.egg/webapp/content &lt;br /&gt;&lt;br /&gt;Here's an example config for nginx:&lt;br /&gt;&lt;br /&gt;server { &lt;br /&gt;&amp;nbsp; server_name graphite.example.com ; &lt;br /&gt;&amp;nbsp; location / { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; proxy_pass http://localhost:9037/; &lt;br /&gt;&amp;nbsp; } &lt;br /&gt;&amp;nbsp; location /content {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; root /opt/graphite/0.9.9/lib/python2.7/site-packages/graphite_web-0.9.9-py2.7.egg/webapp;&lt;br /&gt;&amp;nbsp; }&lt;/p&gt;&#13;
&lt;p&gt;}&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;h4&gt;Add data&lt;/h4&gt;&#13;
&lt;p&gt;To track the number of files in your home dir over time, run this in a loop or cron:&lt;/p&gt;&#13;
&lt;p&gt;echo demo.numFiles `ls -1 ~ | wc -l` `date +%s` | nc -q 0 localhost 2003&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://github.com/20minutes/galena"&gt;Galena&lt;/a&gt; is a python module that does the same thing.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>http://drewp.quickwitretort.com/2011/07/16/0</id>
    <title>Released comment system</title>
    <published>2011-07-16T22:54:28.859486-07:00</published>
    <updated>2011-07-16T22:54:28.859486-07:00</updated>
    <link href="http://drewp.quickwitretort.com/2011/07/16/0" type="text/html" rel="alternate"/>
    <content type="html">&lt;p&gt;I just released the code for the comment system I'm using on this blog, another secret blog, and my photo site which is also secret. The comment system is implemented as a web service you run internally. Your interesting web site calls over to commentServe when it wants to show existing comments or render an add-comment form.&lt;/p&gt;&#13;
&lt;p&gt;It's a poor man's self-hosted Disqus, but it still has spam filtering, notifications, HTML support, RDF integration, and some other things you wouldn't normally have if you just hacked one of these together for a day. (You'd probably exceed my system if you hacked for &lt;em&gt;two&lt;/em&gt; days, however.)&lt;/p&gt;&#13;
&lt;p&gt;Source:&amp;nbsp;&lt;a href="http://bigasterisk.com/darcs/?r=commentserve;a=tree"&gt;http://bigasterisk.com/darcs/?r=commentserve;a=tree&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;Readme:&amp;nbsp;&lt;a href="http://bigasterisk.com/darcs/?r=commentserve;a=headblob;f=/readme"&gt;http://bigasterisk.com/darcs/?r=commentserve;a=headblob;f=/readme&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;Github mirror:&amp;nbsp;&lt;a href="https://github.com/drewp/commentserve"&gt;https://github.com/drewp/commentserve&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>http://drewp.quickwitretort.com/2011/07/08/0</id>
    <title>Fix for a nevow/formless/annotate/zope.interface bug</title>
    <published>2011-07-08T15:32:19.730245-07:00</published>
    <updated>2011-07-08T15:32:19.730245-07:00</updated>
    <link href="http://drewp.quickwitretort.com/2011/07/08/0" type="text/html" rel="alternate"/>
    <content type="html">&lt;pre&gt;    from nevow import tags as T&#13;
  File "/usr/lib/python2.6/dist-packages/nevow/__init__.py", line 143, in &#13;
    load(basic_adapters)&#13;
  File "/usr/lib/python2.6/dist-packages/nevow/__init__.py", line 29, in load&#13;
    registerAdapter(_namedAnyWithBuiltinTranslation(a),&#13;
  File "/usr/lib/python2.6/dist-packages/nevow/util.py", line 183, in _namedAnyWithBuiltinTranslation&#13;
    return namedAny(name)&#13;
  File "/home/drewp/projects-local/ffg/eggs/Twisted-10.0.0-py2.6-linux-x86_64.egg/twisted/python/reflect.py", line 464, in namedAny&#13;
    topLevelPackage = _importAndCheckStack(trialname)&#13;
  File "/home/drewp/projects-local/ffg/eggs/Twisted-10.0.0-py2.6-linux-x86_64.egg/twisted/python/reflect.py", line 400, in _importAndCheckStack&#13;
    return __import__(importName)&#13;
  File "/usr/lib/python2.6/dist-packages/formless/__init__.py", line 9, in &#13;
    from formless.annotate import *&#13;
  File "/usr/lib/python2.6/dist-packages/formless/annotate.py", line 851, in &#13;
    TypedInterface = MetaTypedInterface('TypedInterface', (InterfaceClass('TypedInterface'), ), {})&#13;
  File "/usr/lib/python2.6/dist-packages/formless/annotate.py", line 731, in __new__&#13;
    _typedInterfaceMetadata[cls, '__id__'] = nextId()&#13;
  File "/home/drewp/projects-local/ffg/eggs/zope.interface-3.6.4-py2.6-linux-x86_64.egg/zope/interface/interface.py", line 685, in __hash__&#13;
    return hash((self.__name__, self.__module__))&#13;
AttributeError: 'MetaTypedInterface' object has no attribute '__name__'&#13;
&#13;
&lt;/pre&gt; &#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
 &#13;
&lt;p&gt;That's an annoying error I just started getting, maybe with my Ubuntu 11.04 upgrade, or maybe from something else. Here is a workaround:&lt;/p&gt;&#13;
 &#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#13;
 &lt;pre&gt;from zope.interface.interface import InterfaceClass&#13;
def __hash__(self):&#13;
    return hash((getattr(self, __name__, ''), self.__module__))&#13;
InterfaceClass.__hash__ = __hash__&#13;
&lt;/pre&gt; &#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>http://drewp.quickwitretort.com/2011/06/13/0</id>
    <title>House power measurement plan</title>
    <published>2011-06-13T01:07:40.573919-07:00</published>
    <updated>2011-06-13T01:07:40.573919-07:00</updated>
    <link href="http://drewp.quickwitretort.com/2011/06/13/0" type="text/html" rel="alternate"/>
    <content type="html">&lt;p&gt;&lt;a href="http://hackaday.com/2011/05/13/monitor-your-homes-power-usage-on-the-cheap/"&gt;This article&lt;/a&gt; taught me how new home power meters often have an IR LED that pulses with power usage. &lt;a href="http://www.flickr.com/photos/blalor/3876765214/"&gt;blalor checked his meter&lt;/a&gt; and found a 10ms pulse.&lt;/p&gt;&#13;
&lt;p&gt;I took a camcorder out to my own meter (&lt;a href="http://www.google.com/search?q=kv2cs+meter&amp;amp;hl=en&amp;amp;prmd=ivns&amp;amp;source=lnms&amp;amp;tbm=isch"&gt;GE kv2cs&lt;/a&gt;) and it does seem to be pulsing out the front. My plan is to follow the guides on &lt;a href="http://irmetermon.git.sourceforge.net/git/gitweb.cgi?p=irmetermon/irmetermon;a=tree;f=doc;hb=HEAD"&gt;irmetermon&lt;/a&gt;, probably just schematic.adc, and connect my phototransistor to a pin on the closest parallel port which I'm already interfacing several other things to.&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://photo.bigasterisk.com/phonecam/dt/CIMG1460.jpg?size=medium" alt="" width="187" height="250" /&gt;&lt;/p&gt;&#13;
&lt;p&gt;I hope I'll be able to read the parport fast enough to not miss pulses, and I hope I don't get too much extra IR light coming from the sun. That parport will eventually change to an arduino, and then I'll be able more easily to do the analog sensing and calibration that the irmetermon project is mainly about.&lt;/p&gt;&#13;
&lt;p&gt;The goal is to get instantaneous power usage data into my &lt;a href="http://graphite.wikidot.com/"&gt;graphite&lt;/a&gt; server, where I will be able to plot it along many other measurements, including solar panel generation, temperature, ISP bandwidth, and computer clock speeds.&lt;/p&gt;&#13;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content>
  </entry>
</feed>


