<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/alex-2012.css" ?>
<rss version="2.0"
    xmlns:wiki="http://purl.org/rss/1.0/modules/wiki/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:cc="http://web.resource.org/cc/"
    xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<title>Alex Schroeder: Diary</title>
<link>http://alexschroeder.ch/wiki/Diary</link>
<atom:link href="http://www.google.com/profiles/kensanata" rel="me" type="text/html" />
<atom:link href="http://alexschroeder.ch/wiki?action=rss;full=1" rel="self" type="application/rss+xml" />
<description>The Homepage of Alex Schroeder.</description>
<pubDate>Wed, 19 Jun 2013 20:04:43 GMT</pubDate>
<lastBuildDate>Wed, 19 Jun 2013 20:04:43 GMT</lastBuildDate>
<generator>Oddmuse</generator>
<copyright>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation.</copyright>
<cc:license>http://www.gnu.org/copyleft/fdl.html</cc:license>
<image>
<url>http://alexschroeder.ch/pics/alex.png</url>
<title>Alex Schroeder: Diary</title>
<link>http://alexschroeder.ch/wiki</link>
</image>

<item>
<title>Perl and UTF-8</title>
<link>http://alexschroeder.ch/wiki/2012-07-20_Perl_and_UTF-8</link>
<guid>http://alexschroeder.ch/wiki/2012-07-20_Perl_and_UTF-8</guid>
<description>&lt;p&gt;I maintain a wiki engine called &lt;a class="local" href="http://alexschroeder.ch/wiki/Oddmuse"&gt;Oddmuse&lt;/a&gt;. It&amp;#x2019;s the software used to run my blog, for example. It is written in an older scripting language called &lt;em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;"&gt;Perl&lt;/em&gt;. &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/Perl"&gt;Perl&lt;/a&gt; predates &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/Unicode"&gt;Unicode&lt;/a&gt;. That&amp;#x2019;s why the use of &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/UTF-8"&gt;UTF-8&lt;/a&gt; or &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/UTF-16"&gt;UTF-16&lt;/a&gt; is not mandated. That, in turn, means that usually bytes are interpreted as an UTF-8 encoded character is only visible as two bytes.&lt;/p&gt;&lt;p&gt;Consider this regular expression to match WikiWords: &lt;code&gt;[A-Z][a-z]+[A-Z][a-z]+&lt;/code&gt;&lt;/p&gt;&lt;p&gt;How would you extend it to parse &lt;em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;"&gt;ÃlPlattform&lt;/em&gt;?&lt;/p&gt;&lt;p&gt;Assume the following Perl code was written in a source file that was UTF-8 encoded:&lt;/p&gt;&lt;pre class="real"&gt;$str = "OelPlattform";
print "OelPlattform YES\n" if $str =~ /[[:upper:]][[:lower:]]+[[:upper:]]\w+/;
$str = "ÃlPlattform";
print "ÃlPlattform YES\n" if $str =~ /[[:upper:]][[:lower:]]+[[:upper:]]\w+/;&lt;/pre&gt;&lt;p&gt;This will just print &lt;code&gt;OelPlattform YES&lt;/code&gt; because what looks like &amp;#x201c;ÃlPlattform&amp;#x201d; actually starts with the bytes C3 96 and C3 is not an upper case letter. It&amp;#x2019;s actually unclear what it is. In a Latin-1 environment the C3 would print as Ã&amp;#x2014;the dreaded sign of encoding errors!&lt;/p&gt;&lt;p&gt;I wanted to keep Oddmuse encoding agnostic. Users could specify a different encoding which would be served together with the page HTML such that they could have wikis using &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/GB%202312"&gt;GB 2312&lt;/a&gt;. This is why Oddmuse contained the following line and similar code:&lt;/p&gt;&lt;pre class="real"&gt;# we treat input and output as bytes
eval { local $SIG{__DIE__}; binmode(STDOUT, ":raw"); };&lt;/pre&gt;&lt;p&gt;This resulted in problems when some packages I was using did in fact produce UTF-8 and so I had to use code as follows:&lt;/p&gt;&lt;pre class="real"&gt;eval { local $SIG{__DIE__}; binmode(STDOUT, ":utf8"); } if $HttpCharset eq 'UTF-8';
print RSS($3 ? $3 : 15, split(/\s+/, UnquoteHtml($4)));
eval { local $SIG{__DIE__}; binmode(STDOUT, ":raw"); };&lt;/pre&gt;&lt;p&gt;I&amp;#x2019;m not sure why I surrounded it all with an eval&amp;#x2014;I assume it was to support an older version of Perl but I&amp;#x2019;m not sure.&lt;/p&gt;&lt;p&gt;Ok, so I wanted to get rid of all that.&lt;/p&gt;&lt;p&gt;The solution seems deceptively simple: add &lt;code&gt;use utf8;&lt;/code&gt; to the source files and open all files using the UTF-8 encoding layer.&lt;/p&gt;&lt;p&gt;When printing UTF-8 to STDOUT, you need to tell Perl that STDOUT can in fact handle multi-byte characters. Since the HTML produced is UTF-8 encoded, I know that this is true. If you don&amp;#x2019;t, you&amp;#x2019;ll get &amp;#x201c;wide character in print&amp;#x201d; warnings.&lt;/p&gt;&lt;pre class="real"&gt;binmode(STDOUT, ':utf8');&lt;/pre&gt;&lt;p&gt;You need to be careful with all input and output, however.&lt;/p&gt;&lt;pre class="real"&gt;open(F, '&amp;lt;:encoding(UTF-8)', $RcFile);&lt;/pre&gt;&lt;p&gt;The same is true for output:&lt;/p&gt;&lt;pre class="real"&gt;open(OUT, '&amp;gt;:encoding(UTF-8)', $file)
  or ReportError(Ts('Cannot write %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');&lt;/pre&gt;&lt;p&gt;Oddmuse also offers the ability to &lt;em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;"&gt;include&lt;/em&gt; other pages (&lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/Transclusion"&gt;Transclusion&lt;/a&gt;) and to produce feeds. This can be a problem. The default page processing is to parse the raw text and start printing HTML as soon as possible because I have always felt that it was more expedient to start printing the top of the page while the rest was still being parsed. What happens when I don&amp;#x2019;t want to do this, eg. I&amp;#x2019;m in the middle of building the RSS feed?&lt;/p&gt;&lt;p&gt;The solution I had been using was to redirect STDOUT to a variable. Perl calls this a &amp;#x201c;memory file.&amp;#x201d; The problem is the encoding of this memory file:&lt;/p&gt;&lt;p&gt;Here&amp;#x2019;s what I had to write:&lt;/p&gt;&lt;pre class="real"&gt;open(STDOUT, '&amp;gt;', \$page) or die "Can't open memory file: $!";
binmode(STDOUT, ":utf8");
PrintPageHtml();
utf8::decode($page);&lt;/pre&gt;&lt;p&gt;I think this works because &lt;code&gt;binmode&lt;/code&gt; tells all the &lt;code&gt;print&lt;/code&gt; instructions that it&amp;#x2019;s ok to print multi-byte characters and &lt;code&gt;utf8::decode&lt;/code&gt; makes sure that all those bytes are in fact decoded back to Perl&amp;#x2019;s internal representation.&lt;/p&gt;&lt;p&gt;Then I discovered that I needed to look at the &lt;em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;"&gt;bytes&lt;/em&gt; if I wanted to URL-encode strings:&lt;/p&gt;&lt;pre class="real"&gt;utf8::encode($str); # turn to byte string
my @letters = split(//, $str);
my %safe = map {$_ =&amp;gt; 1} ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '-', '_', '.', '!', '~', '*', "'", '(', ')', '#');
foreach my $letter (@letters) {
  $letter = sprintf("%%%02x", ord($letter)) unless $safe{$letter};
}&lt;/pre&gt;&lt;p&gt;Now that I&amp;#x2019;m looking at the above I wonder what sort of bugs I&amp;#x2019;m introducing with the inverse operation that I haven&amp;#x2019;t changed:&lt;/p&gt;&lt;pre class="real"&gt;$str =~ s/%([0-9a-f][0-9a-f])/chr(hex($1))/ge;&lt;/pre&gt;&lt;p&gt;I feel that this requires a call to &lt;code&gt;utf8::decode&lt;/code&gt; when done! Strangely enough none of my tests have picked this up. &lt;img class="smiley" src="http://www.emacswiki.org/pics/question.png" alt="question" /&gt;&lt;/p&gt;&lt;p&gt;(Actually I think I know why I haven&amp;#x2019;t stumbled across this problem: I only use the function to decode the Cookie, and all the functions accessing the cookie go through an extra encoding/decoding step that would not be necessary if I had fixed the URL-decoding function. &lt;img class="smiley" src="http://www.emacswiki.org/pics/lightbulb.png" alt="lightbulb" /&gt;)&lt;/p&gt;&lt;p&gt;Another problem I stumbled upon: directories. Directories often ended up Latin-1 encoded.&lt;/p&gt;&lt;pre class="real"&gt;utf8::encode($newdir);
return if -d $newdir;
mkdir($newdir, 0775)
  or ReportError(Ts('Cannot create %s', $newdir) . ": $!", '500 INTERNAL SERVER ERROR');&lt;/pre&gt;&lt;p&gt;The reason I didn&amp;#x2019;t discover I had the same problem with filenames was that I&amp;#x2019;m using a compatibility layer on my Mac when I do my developments. The Mac uses UTF-8 NFD instead of UTF-8 NFC as is the standard on the web. Thus if you take bytes encoding a filename from the web and create the file, or if you go the other way, you have a problem. I store the index of all pages in a files. When a new page is created, I get the page name (NCF encoded) from the web, and store it in a file. When I read the file, the content contains the NFC bytes and with these, I cannot find the NFD encoded file (because the filesystem changed the encoding as it wrote the file). I hated it so much. Thus, the Mac compatibility layer does an extra encoding and decoding to get everything from NFD to NFC&amp;#x2014;and thereby protected me from this error.&lt;/p&gt;&lt;p&gt;As soon as I installed it on my sites, however&amp;#x2014;they all use Debian and ext3 filesystems, I think&amp;#x2014;I had a problem.&lt;/p&gt;&lt;p&gt;The necessary fix:&lt;/p&gt;&lt;pre class="real"&gt;utf8::encode($file);
if (open(IN, '&amp;lt;:encoding(UTF-8)', $file)) {
  local $/ = undef;   # Read complete files
  my $data=&amp;lt;IN&amp;gt;;
  close IN;
  return (1, $data);
}&lt;/pre&gt;&lt;p&gt;And:&lt;/p&gt;&lt;pre class="real"&gt;utf8::encode($file);
open(OUT, '&amp;gt;:encoding(UTF-8)', $file)
  or ReportError(Ts('Cannot write %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
print OUT  $string;
close(OUT);&lt;/pre&gt;&lt;p&gt;Another stumbling block was that the non-breaking space was no longer just a byte sequence like any other, namely C2 A0. Perl suddenly recognized it as &lt;em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;"&gt;whitespace&lt;/em&gt;! This is a problem if a path contains non-breaking spaces! The old code translated spaces to underscore characters, so that wasn&amp;#x2019;t really a possibility. But whenever I had been &amp;#x201c;smart&amp;#x201d; and used a non-breaking space, I now had a problem. The &lt;code&gt;glob&lt;/code&gt; function splits its arguments on &lt;em style="text-decoration: underline; font-style: normal;"&gt;whitespace&lt;/em&gt;. Where there was one pattern, I now had two broken patterns!&lt;/p&gt;&lt;p&gt;Here&amp;#x2019;s an example:&lt;/p&gt;&lt;pre class="real"&gt;glob(GetKeepDir(shift) . '/*.kp'); # files such as 1.kp, 2.kp, etc.&lt;/pre&gt;&lt;p&gt;Here&amp;#x2019;s another example:&lt;/p&gt;&lt;pre class="real"&gt;foreach (glob("$PageDir/*/*.pg $PageDir/*/.*.pg"))&lt;/pre&gt;&lt;p&gt;The solution is to &lt;code&gt;use File::Glob ':glob'&lt;/code&gt; and replace every occurence of &lt;code&gt;glob&lt;/code&gt; with &lt;code&gt;bsd_glob&lt;/code&gt;. Wow, my application was very much unsuited to filenames containing whitespace and I hadn&amp;#x2019;t even realized it!&lt;/p&gt;&lt;pre class="real"&gt;foreach (bsd_glob("$PageDir/*/*.pg"), bsd_glob("$PageDir/*/.*.pg"))&lt;/pre&gt;&lt;p&gt;Remember the regular expression to detect wiki words I used at the top? This was the actual regular expression I had been using:&lt;/p&gt;&lt;pre class="real"&gt;$WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';&lt;/pre&gt;&lt;p&gt;Essentially wiki words only worked for a first letter containing an ASCII upper case letter.&lt;/p&gt;&lt;p&gt;At first, I switched this to the following regular expression (trying to minimize changes):&lt;/p&gt;&lt;pre class="real"&gt;$WikiWord = '[A-Z]+[a-z\x{0080}-\x{ffff}]+[A-Z][A-Za-z\x{0080}-\x{ffff}]*';&lt;/pre&gt;&lt;p&gt;It turns out that Perl 5.8 chokes on this regular expression, howeveer. FFFE and FFFF are noncharacters. I had to change the regular expression.&lt;/p&gt;&lt;pre class="real"&gt;$WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*'; # exclude noncharacters FFFE and FFFF&lt;/pre&gt;&lt;p&gt;I&amp;#x2019;m sure this list isn&amp;#x2019;t complete but I&amp;#x2019;m sure it&amp;#x2019;s long enough to illustrate my main point: this is painful. It&amp;#x2019;s HTML quoting all over again.&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed fÃ¼r diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Software"&gt;Software&lt;/a&gt; &lt;a class="feed tag" title="Feed fÃ¼r diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Software"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Fri, 20 Jul 2012 16:10:25 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2012-07-20_Perl_and_UTF-8</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>new</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>1</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2012-07-20_Perl_and_UTF-8</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2012-07-20_Perl_and_UTF-8</wiki:diff>
<category>Perl</category>
<category>Software</category>
</item>

<item>
<title>Oddmuse, Venus and Perl</title>
<link>http://alexschroeder.ch/wiki/2011-10-07_Oddmuse%2c_Venus_and_Perl</link>
<guid>http://alexschroeder.ch/wiki/2011-10-07_Oddmuse%2c_Venus_and_Perl</guid>
<description>&lt;div class="right" style="float: right"&gt;&lt;p&gt;&lt;img class="url http" src="http://www.emacswiki.org/pics/oddmuse-logo.png" alt="http://www.emacswiki.org/pics/oddmuse-logo.png" /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;I&amp;#x2019;ve been working on a &lt;a class="url http outside" href="http://campaignwiki.org/submit"&gt;submission form&lt;/a&gt; for the &lt;a class="near" title="Names" href="http://campaignwiki.org/planet"&gt;Old School RPG Planet&lt;/a&gt;. Today I added another little feature. This is how I like to develop code. No time pressure. One little step at a time. Keep polishing it.&lt;/p&gt;&lt;p&gt;The planet uses &lt;a class="url http outside" href="http://intertwingly.net/code/venus/"&gt;Planet Venus&lt;/a&gt; to collect the RSS and Atom feeds of many of the Old School RPG blogs out there. Planet Venus allows you to get the list of feeds via an URL. I&amp;#x2019;m hosting the &lt;a class="url http outside" href="http://campaignwiki.org/wiki/Planet/Feeds"&gt;list of feeds on Campaign Wiki&lt;/a&gt; itself (&lt;a class="url http outside" href="http://campaignwiki.org/wiki/Planet/raw/Feeds"&gt;raw format&lt;/a&gt;). As you can see, it the format doesn&amp;#x2019;t look nice.&lt;/p&gt;&lt;p&gt;The thing I did, therefore, was to write a script that makes it easy for people who are not into the technical details to submit new blogs. It also makes it easier for me to submit new blogs!&lt;/p&gt;&lt;p&gt;The things it handles:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If you submit an invalid URL, it will prepend &lt;code&gt;http://&lt;/code&gt; and try again.&lt;/li&gt;&lt;li&gt;If it looks like we already have a similar looking feed on our page, it requires a confirmation by the user.&lt;/li&gt;&lt;li&gt;If you submit a web page, it will look for alternative links with MIME types &lt;code&gt;application/rss+xml&lt;/code&gt;, &lt;code&gt;application/atom+xml&lt;/code&gt;, &lt;code&gt;application/xml&lt;/code&gt; (yeah) and &lt;code&gt;text/xml&lt;/code&gt; (just making sure) and allow the user to pick one of them.&lt;/li&gt;&lt;li&gt;If you submitted a feed directly instead of a web page, it it uses that instead.&lt;/li&gt;&lt;li&gt;If the feed you picked is served with an invalid content type, it is rejected.&lt;/li&gt;&lt;li&gt;It extracts the title of the feed and adds it to the wiki page, sorting all the entries alphabetically.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I think it&amp;#x2019;s pretty cool.&lt;/p&gt;&lt;p&gt;If you look at the interface, you&amp;#x2019;ll note that it has &lt;a class="url http outside" href="http://campaignwiki.org/submit/source"&gt;a link to its own source code&lt;/a&gt;. I love this little Perl trick:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Add &lt;code&gt;__DATA__&lt;/code&gt; at the end of the source file. Usually you would add actual data at the end. The script could read it using the DATA file handle.&lt;/li&gt;&lt;li&gt;Serve source code using &lt;code&gt;seek DATA, 0, 0; print "Content-type: text/plain; charset=UTF-8\r\n\r\n", &amp;lt;DATA&amp;gt;;&lt;/code&gt; This resets the current position of the DATA file handle to the beginning of the source file. Tadaa! &lt;img class="smiley" src="http://www.emacswiki.org/pics/smile.png" alt=":)" /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Oddmuse"&gt;Oddmuse&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Oddmuse"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Venus"&gt;Venus&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Venus"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Wiki"&gt;Wiki&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Wiki"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Fri, 07 Oct 2011 20:10:58 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2011-10-07_Oddmuse%2c_Venus_and_Perl</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>new</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>1</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2011-10-07_Oddmuse%2c_Venus_and_Perl</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2011-10-07_Oddmuse%2c_Venus_and_Perl</wiki:diff>
<category>Oddmuse</category>
<category>Venus</category>
<category>Perl</category>
<category>Wiki</category>
</item>

<item>
<title>Map Drawing Using Polygons</title>
<link>http://alexschroeder.ch/wiki/2011-04-30_Map_Drawing_Using_Polygons</link>
<guid>http://alexschroeder.ch/wiki/2011-04-30_Map_Drawing_Using_Polygons</guid>
<description>&lt;p&gt;I&amp;#x2019;m currently working on randomly generating islands using the ideas presented in &lt;a class="url http outside" href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt; Polygonal Map Generation&lt;/a&gt; by Amit. Check out his &lt;a class="url http outside" href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2.swf"&gt;Flash demo&lt;/a&gt;! I am nowhere as far, yet. I&amp;#x2019;m writing my code in Perl and &lt;a class="url http outside" href="http://campaignwiki.org/monones.pl"&gt;producing SVG output&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/kensanata/5671163434/" class="url http"&gt;&lt;img class="url http" src="http://farm6.static.flickr.com/5303/5671163434_e3b86d4dde.jpg" alt="http://farm6.static.flickr.com/5303/5671163434_e3b86d4dde.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;See below for source code used. I&amp;#x2019;d install it on a public server, but unfortunately there are quite some dependencies…&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Maps"&gt;Maps&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Maps"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Perl"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=SVG"&gt;SVG&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/SVG"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre class="real"&gt;#! /usr/bin/perl -w
# Copyright (C) 2011  Alex Schroeder &amp;lt;alex@gnu.org&amp;gt;
#
# 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 3 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, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.

use strict;
use CGI qw(:standard);
use SVG;
use Math::Geometry::Voronoi;
use Class::Struct;
use Math::Fractal::Noisemaker;
use List::Util qw(min max);
use Data::Dumper;

my $points = 3000;
my $width  = 1000;
my $height =  550;
my $center_x = $width / 2;
my $center_y = $height / 2;
my $radius = 500;

my %color = (beach =&amp;gt; '#a09077',
	     ocean =&amp;gt; '#44447a',);

struct World =&amp;gt; { points =&amp;gt; '@',
		  centroids =&amp;gt; '@',
		  voronoi =&amp;gt; '$',
		  height =&amp;gt; '@',
		};

sub add_random_points {
  my ($world) = @_;
  for (my $i = 0; $i &amp;lt; $points; $i++) {
    push(@{$world-&amp;gt;points}, [rand($width), rand($height)]);
  };
  # print(join("\n", map {join(",", $_-&amp;gt;[0], $_-&amp;gt;[1])} @{$world-&amp;gt;points}));
  return $world;
}

sub add_voronoi {
  my ($world) = @_;
  $world-&amp;gt;voronoi(Math::Geometry::Voronoi-&amp;gt;new(points =&amp;gt; $world-&amp;gt;points));
  $world-&amp;gt;voronoi-&amp;gt;compute;
}

sub add_centroids {
  my ($world) = @_;
  $world-&amp;gt;centroids([]); # clear
  foreach my $polygon ($world-&amp;gt;voronoi-&amp;gt;polygons) {
    push(@{$world-&amp;gt;centroids}, centroid($polygon));
  }
}

sub centroid {
  my ($cx, $cy) = (0, 0);
  my $A = 0;
  my $polygon = shift;
  my ($point_index, @points) = @$polygon; # see Math::Geometry::Voronoi
  my $point = $points[$#points];
  my ($x0, $y0) = ($point-&amp;gt;[0], $point-&amp;gt;[1]);
  for $point (@points) {
    my ($x1, $y1) = ($point-&amp;gt;[0], $point-&amp;gt;[1]);
    $cx += ($x0 + $x1) * ($x0 * $y1 - $x1 * $y0);
    $cy += ($y0 + $y1) * ($x0 * $y1 - $x1 * $y0);
    $A += ($x0 * $y1 - $x1 * $y0);
    ($x0, $y0) = ($x1, $y1);
  }
  $A /= 2;
  $cx /= 6 * $A;
  $cy /= 6 * $A;
  return [$cx, $cy, $point_index];
}

sub add_height {
  my $world = shift;
  $Math::Fractal::Noisemaker::QUIET = 1;
  my $grid = Math::Fractal::Noisemaker::square();
  $world-&amp;gt;height([]); # clear
  my $scale = max($height, $width); # grid is a square
  foreach my $point (@{$world-&amp;gt;points}) {
    my $x = int($point-&amp;gt;[0]*255/$scale);
    my $y = int($point-&amp;gt;[1]*255/$scale);
    my $h = 0; # we must not skip any points!
    $h = $grid-&amp;gt;[$x]-&amp;gt;get($y) / 255
      unless $x &amp;lt; 0 or $y &amp;lt; 0 or $x &amp;gt; 255 or $y &amp;gt; 255;
    push(@{$world-&amp;gt;height}, $h);
  }
}

sub raise_point {
  my ($world, $x, $y, $radius) = @_;
  my $i = 0;
  foreach my $point (@{$world-&amp;gt;points}) {
    my $dx = $point-&amp;gt;[0] - $x;
    my $dy = $point-&amp;gt;[1] - $y;
    my $d = sqrt($dx * $dx + $dy * $dy);
    my $v = max(0, $world-&amp;gt;height-&amp;gt;[$i] - $d / $radius);
    $world-&amp;gt;height($i, $v);
    $i++;
  }
}

sub svg {
  my $world = shift;
  my $svg = new SVG(-width =&amp;gt; $width,
		    -height =&amp;gt; $height, );
  foreach my $polygon ($world-&amp;gt;voronoi-&amp;gt;polygons) {
    my ($point_index, @points) = @$polygon; # see Math::Geometry::Voronoi
    my $x = $world-&amp;gt;points-&amp;gt;[$point_index]-&amp;gt;[0];
    my $y = $world-&amp;gt;points-&amp;gt;[$point_index]-&amp;gt;[1];
    next if $x &amp;lt; 0 or $y &amp;lt; 0 or $x &amp;gt; $width or $y &amp;gt; $height;
    my $z = int($world-&amp;gt;height-&amp;gt;[$point_index] * 255);
    my $color = $z == 0 ? $color{ocean} : "rgb($z,$z,$z)";
    my $path = join(",", map { map { int } @$_ } @points);
    $svg-&amp;gt;polygon(points =&amp;gt; $path,
		  fill =&amp;gt; $color,
		  style =&amp;gt; { 'stroke-width' =&amp;gt; 1,
			     'stroke' =&amp;gt; 'black'});
  }
  return $svg-&amp;gt;xmlify();
}

sub response {
  print header(-type=&amp;gt;'image/svg+xml');
  print shift;
}

sub main {
  if (path_info eq '/source') {
    seek DATA, 0, 0;
    print "Content-type: text/plain; charset=UTF-8\r\n\r\n", &amp;lt;DATA&amp;gt;;
  } else {
    srand(param('seed') || time);
    my $world = new World;
    add_random_points($world, $points);
    add_voronoi($world);
    for (my $i = 2; $i--; ) {
      # Lloyd Relaxation
      add_centroids($world);
      $world-&amp;gt;points($world-&amp;gt;centroids);
      add_voronoi($world);
    }
    # skip corner improvement
    # skip Delaunay triangulation
    add_height($world);
    raise_point($world, $center_x, $center_y, $radius);
    # draw
    response(svg($world));
  }
}

main ();

__DATA__&lt;/pre&gt;</description>
<pubDate>Sat, 30 Apr 2011 00:05:50 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2011-04-30_Map_Drawing_Using_Polygons</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>new</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>1</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2011-04-30_Map_Drawing_Using_Polygons</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2011-04-30_Map_Drawing_Using_Polygons</wiki:diff>
<category>Maps</category>
<category>Perl</category>
<category>SVG</category>
</item>

<item>
<title>Web Standards Dream Bubble</title>
<link>http://alexschroeder.ch/wiki/2010-10-15_Web_Standards_Dream_Bubble</link>
<guid>http://alexschroeder.ch/wiki/2010-10-15_Web_Standards_Dream_Bubble</guid>
<description>&lt;p&gt;I maintain the &lt;a class="near" title="Names" href="http://campaignwiki.org/planet"&gt;Old School RPG Planet&lt;/a&gt;. The list of feeds it manages is saved &lt;a class="inter CW outside" href="http://campaignwiki.org/wiki/Planet/Feeds"&gt;on a wiki page&lt;/a&gt;. I wanted to write a little script that will allow me to quickly add feeds to that list. And I did! There&amp;#x2019;s now a way to &lt;a class="url http outside" href="http://www.campaignwiki.org/submit"&gt;submit new feeds to the feed&lt;/a&gt; instead of editing the wiki page.&lt;/p&gt;&lt;p&gt;The problem? The thing tries to parse web pages, trying to discover feed addresses. And that works well for sites that validate. But the two first Blogspot sites I tried each had over two hundred errors! Once the markup is borked, parsing doesn&amp;#x2019;t work, and thus feed discovery doesn&amp;#x2019;t work.&lt;/p&gt;&lt;p&gt;Now, if I need to work around broken markup, I start wondering why tried to standardize HTML… What a glorious waste of time! In the end, we just treat it as &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/tag soup"&gt;tag soup&lt;/a&gt; anyway. &lt;img class="smiley" src="http://www.emacswiki.org/pics/evil.png" alt="&amp;gt;{" /&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x2019;re still interested &lt;a class="url http outside" href="http://www.campaignwiki.org/submit/source"&gt;in the source code&lt;/a&gt;, no problem. Lately all my CGI-scripts are able to spew forth their source code.&lt;/p&gt;&lt;p&gt;Unfortunately it is not complete, yet. It doesn&amp;#x2019;t update the wiki page. I didn&amp;#x2019;t bother once I realized that the entire parsing idea was not going to work. &lt;img class="smiley" src="http://www.emacswiki.org/pics/cry.png" alt=":'(" /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: Wohoo, replaced HTML and XML parsing with regular expression matching, wrote what I needed, and finished the script! &lt;a class="url http number" href="http://www.campaignwiki.org/submit"&gt;&lt;span&gt;&lt;span class="bracket"&gt;[&lt;/span&gt;1&lt;span class="bracket"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;img class="smiley" src="http://www.emacswiki.org/pics/smile.png" alt=":)" /&gt;&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Web"&gt;Web&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Web"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Standards"&gt;Standards&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/Standards"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=HTML"&gt;HTML&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex/feed/full/HTML"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Sat, 16 Oct 2010 23:01:09 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2010-10-15_Web_Standards_Dream_Bubble</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>3</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2010-10-15_Web_Standards_Dream_Bubble</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2010-10-15_Web_Standards_Dream_Bubble</wiki:diff>
<category>Web</category>
<category>Perl</category>
<category>Standards</category>
<category>HTML</category>
</item>

<item>
<title>I hate the Perl SMTP libraries</title>
<link>http://alexschroeder.ch/wiki/2009-10-02_I_hate_the_Perl_SMTP_libraries</link>
<guid>http://alexschroeder.ch/wiki/2009-10-02_I_hate_the_Perl_SMTP_libraries</guid>
<description>&lt;p&gt;At home I have Net::SMTP::TLS and Net::SMTP::SSL installed and I&amp;#x2019;ve managed to use both to send mail via my Google account.&lt;/p&gt;&lt;p&gt;On one of my hosting services, I have only Net::SMTP::SSL, and it just won&amp;#x2019;t work.&lt;/p&gt;&lt;p&gt;Debug output at home:&lt;/p&gt;&lt;pre class="real"&gt;Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt; Net::SMTP::SSL(1.01)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;   IO::Socket::SSL(1.24)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;     IO::Socket::INET(1.31)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;       IO::Socket(1.31)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;         IO::Handle(1.28)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;           Exporter(5.58)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;   Net::Cmd(2.29)
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 220 mx.google.com ESMTP 24sm915314eyx.9
Net::SMTP::SSL=GLOB(0x186fc04)&amp;gt;&amp;gt;&amp;gt; EHLO localhost.localdomain
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250-mx.google.com at your service, [80.219.173.68]
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250-SIZE 35651584
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250-8BITMIME
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250-AUTH LOGIN PLAIN
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250-ENHANCEDSTATUSCODES
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 250 PIPELINING
Net::SMTP::SSL=GLOB(0x186fc04)&amp;gt;&amp;gt;&amp;gt; AUTH LOGIN
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 334 VXNlcm5hbWU6
Net::SMTP::SSL=GLOB(0x186fc04)&amp;gt;&amp;gt;&amp;gt; a2Vuc2FuYXRh
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 334 UGFzc3dvcmQ6
Net::SMTP::SSL=GLOB(0x186fc04)&amp;gt;&amp;gt;&amp;gt; VGgsYmFpZA==
Net::SMTP::SSL=GLOB(0x186fc04)&amp;lt;&amp;lt;&amp;lt; 235 2.7.0 Accepted
Net::SMTP::SSL=GLOB(0x186fc04)&amp;gt;&amp;gt;&amp;gt; MAIL FROM:&amp;lt;kensanata@gmail.com&amp;gt;&lt;/pre&gt;&lt;p&gt;Notice the &lt;b&gt;AUTH LOGIN&lt;/b&gt; command.&lt;/p&gt;&lt;p&gt;Debug output on my host:&lt;/p&gt;&lt;pre class="real"&gt;Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt; Net::SMTP::SSL(1.01)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;   IO::Socket::SSL(1.16)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;     IO::Socket::INET(1.31)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;       IO::Socket(1.30_01)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;         IO::Handle(1.27)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;           Exporter(5.62)
Net::SMTP::SSL&amp;gt;&amp;gt;&amp;gt;   Net::Cmd(2.29)
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 220 mx.google.com ESMTP 10sm135225eyz.42
Net::SMTP::SSL=GLOB(0xa025520)&amp;gt;&amp;gt;&amp;gt; EHLO localhost.localdomain
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250-mx.google.com at your service, [83.137.100.36]
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250-SIZE 35651584
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250-8BITMIME
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250-AUTH LOGIN PLAIN
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250-ENHANCEDSTATUSCODES
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 250 PIPELINING
Net::SMTP::SSL=GLOB(0xa025520)&amp;gt;&amp;gt;&amp;gt; MAIL FROM:&amp;lt;kensanata@gmail.com&amp;gt;
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 530-5.5.1 Authentication Required. Learn more at                              
Net::SMTP::SSL=GLOB(0xa025520)&amp;lt;&amp;lt;&amp;lt; 530 5.5.1 http://mail.google.com/support/bin/answer.py?answer=14257 10sm135225eyz.42&lt;/pre&gt;&lt;p&gt;Notice the error: &lt;b&gt;Authentication Required&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Why is the same script (I checked twice &amp;#x2013; I sure hope I&amp;#x2019;m not confusing anything) not using the AUTH LOGIN command?&lt;/p&gt;&lt;p&gt;I don&amp;#x2019;t understand.&lt;/p&gt;&lt;pre class="real"&gt;  my $mail = new MIME::Entity-&amp;gt;build(To =&amp;gt; $from, # test!
				     From =&amp;gt; $from,
				     Subject =&amp;gt; 'Test Net::SMTP::SSL',
				     Path =&amp;gt; $fh,
				     Type =&amp;gt; "text/html");
  my $smtp = Net::SMTP::SSL-&amp;gt;new($host, Port =&amp;gt; 465,
				 Debug =&amp;gt; 1);
  $smtp-&amp;gt;auth($user, $password);
  $smtp-&amp;gt;mail($from);
  $smtp-&amp;gt;to($from); # test!
  $smtp-&amp;gt;data;
  $smtp-&amp;gt;datasend($mail-&amp;gt;stringify);
  $smtp-&amp;gt;dataend;
  $smtp-&amp;gt;quit;&lt;/pre&gt;&lt;p&gt;Source is available. &lt;a class="url http number" href="http://cvs.savannah.gnu.org/viewvc/oddmuse/smtp_test.pl?root=oddmuse&amp;amp;view=markup"&gt;&lt;span&gt;&lt;span class="bracket"&gt;[&lt;/span&gt;1&lt;span class="bracket"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Output of &lt;code&gt;perl -MNet::SMTP::SSL -wle 'for (keys %INC) { next
    if m[^/]; $m = $_; $m =~ s[/][::]g; $m =~ s/\.pm$//;  print "$m ",
    $m-&amp;gt;VERSION || "&amp;lt;unknown&amp;gt;" }'&lt;/code&gt; as suggested on #perl:&lt;/p&gt;&lt;table class="user long"&gt;&lt;tr&gt;&lt;th&gt;At home&lt;/th&gt;&lt;th&gt;Remote system&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="real"&gt;Net::SSLeay 1.35
IO::Handle 1.28
List::Util 1.14
SelectSaver 1.00
IO::Socket 1.31
warnings 1.03
Symbol 1.05
Scalar::Util 1.14
IO::Socket::INET 1.31
Exporter 5.58
Errno 1.09
IO::Socket::SSL 1.24
warnings::register 1.00
XSLoader 0.02
Net::Config 1.11
Net::Cmd 2.29
utf8 1.04
Config &amp;lt;unknown&amp;gt;
IO 1.25
IO::Socket::UNIX 1.23
Carp 1.03
bytes 1.01
Exporter::Heavy 5.58
Net::SMTP 2.31
vars 1.01
strict 1.03
Net::SMTP::SSL 1.01
constant 1.04
Socket 1.77
AutoLoader 5.60
DynaLoader 1.05&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre class="real"&gt;Net::SSLeay 1.35
XSLoader 0.08
IO::Handle 1.27
warnings::register 1.01
Net::Config 1.11
List::Util 1.19
SelectSaver 1.01
Net::Cmd 2.29
IO::Socket 1.30_01
warnings 1.06
utf8 1.07
IO::Socket::UNIX 1.23
IO 1.23_01
Symbol 1.06
bytes 1.03
Carp 1.08
Net::SMTP 2.31
Scalar::Util 1.19
Exporter::Heavy 5.62
IO::Socket::INET 1.31
Net::SMTP::SSL 1.01
strict 1.04
vars 1.01
Exporter 5.62
constant 1.13
Socket 1.80
Errno 1.1
IO::Socket::SSL 1.16
AutoLoader 5.63&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Hm&amp;#x2026;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: I found the problem and &lt;a class="url http outside" href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=549524"&gt;submitted a bug&lt;/a&gt;: The remote system is a &lt;b&gt;Debian&lt;/b&gt; system, and the admin installed &lt;b&gt;libnet-smtp-ssl-perl&lt;/b&gt;. If you look at the &lt;b&gt;Net::SMTP&lt;/b&gt; code, however, you&amp;#x2019;ll see the following:&lt;/p&gt;&lt;pre class="real"&gt;sub auth {
  my ($self, $username, $password) = @_;

  eval {
    require MIME::Base64;
    require Authen::SASL;
  } or $self-&amp;gt;set_status(500, ["Need MIME::Base64 and Authen::SASL
todo auth"]), return 0;&lt;/pre&gt;&lt;p&gt;There is therefore a dependency on &lt;b&gt;Authen::SASL&lt;/b&gt;. If you don&amp;#x2019;t have that module, sending your email will fail in a non-obvious way, as seen above. &lt;b&gt;Installing libauthen-sasl-perl fixes the problem.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=SMTP"&gt;SMTP&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:SMTP"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Sat, 03 Oct 2009 22:47:07 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-10-02_I_hate_the_Perl_SMTP_libraries</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>8</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-10-02_I_hate_the_Perl_SMTP_libraries</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-10-02_I_hate_the_Perl_SMTP_libraries</wiki:diff>
<category>Perl</category>
<category>SMTP</category>
</item>

<item>
<title>Astronomy Picture of the Day for Mac OSX Desktop Background</title>
<link>http://alexschroeder.ch/wiki/2009-09-23_Astronomy_Picture_of_the_Day_for_Mac_OSX_Desktop_Background</link>
<guid>http://alexschroeder.ch/wiki/2009-09-23_Astronomy_Picture_of_the_Day_for_Mac_OSX_Desktop_Background</guid>
<description>&lt;p&gt;Based on &lt;a class="url http outside" href="http://www.haroldbakker.com/personal/apod.php"&gt;Harold Bakker's APOD script&lt;/a&gt;, I offer the following solution. I don&amp;#x2019;t keep my computer running, so I just install the following Apple Script as a login item (&amp;#x2192;&amp;#x00a0;System Preferences &amp;#x2192;&amp;#x00a0;Accounts &amp;#x2192;&amp;#x00a0;Login Items):&lt;/p&gt;&lt;pre class="real"&gt;(* Place your with timeout statement within a try... on error statement to prevent the script from 
stopping when a timeout occurs. *)
try
	-- Give the script a three minute timeout to prevent problems when this is run as a login item
	with timeout of 180 seconds
		do shell script "~/bin/apod.pl &amp;gt;&amp;gt; /var/tmp/console.log" -- append the result to the console log
	end timeout
on error errMsg -- display a dialog only if an error occurs
	display dialog errMsg giving up after 10
end try&lt;/pre&gt;&lt;p&gt;You should probably create a new script using the Script Editor on your system, paste the above, and save it as an application. Remember to untick the startup screen checkbox.&lt;/p&gt;&lt;p&gt;You&amp;#x2019;ll notice that it runs a Perl script called /bin/apod.pl &amp;#x2013; you should create that directory, put the following Perl script in it, and make it executable. I keep both apod.app and apod.pl in the same /bin directory.&lt;/p&gt;&lt;pre class="real"&gt;#!/usr/bin/perl

# This script will download the astronomy picture of the day and set
# it as the current desktop background.

# originally by Harold Bakker, harold@haroldbakker.com
# http://www.haroldbakker.com/

# changes by Alex Schroeder &amp;lt;alex@gnu.org&amp;gt;
# http://emacswiki.org/alex/

use strict;
use LWP::UserAgent;
use File::Temp qw/tempfile/;

my $ua = LWP::UserAgent-&amp;gt;new;
my $response = $ua-&amp;gt;get("http://antwrp.gsfc.nasa.gov/apod/astropix.html");
if ($response-&amp;gt;is_success
   and $response-&amp;gt;content =~ /href\="image\/([^\/]+)\/(.*?)"/) {
  my $url = "http://antwrp.gsfc.nasa.gov/apod/image/$1/$2";
  my $filename = $2;
  $response = $ua-&amp;gt;get($url);
  if ($response-&amp;gt;is_success) {
    my ($fh, $tempfile) = tempfile(UNLINK=&amp;gt;0);
    print $fh $response-&amp;gt;content;
    close $fh;
    open(F, "|/usr/bin/osascript") or die "Cannot run Apple Script: $!";
    print F &amp;lt;&amp;lt;END;
tell application "Finder"
	set pFile to POSIX file "$tempfile" as string
	set desktop picture to file pFile
	end tell
END
  } else {
    die $response-&amp;gt;status_line;
  }
} else {
  die $response-&amp;gt;status_line;
}&lt;/pre&gt;&lt;p&gt;This should work fine as long you restart your computer about once a day. I haven&amp;#x2019;t made sure that it will try to reuse images, saving the last one in a save place, etc.&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Mac"&gt;Mac&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Mac"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Desktop"&gt;Desktop&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Desktop"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=APOD"&gt;APOD&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/APOD"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Perl"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Wed, 23 Sep 2009 22:32:46 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-09-23_Astronomy_Picture_of_the_Day_for_Mac_OSX_Desktop_Background</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>2</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-09-23_Astronomy_Picture_of_the_Day_for_Mac_OSX_Desktop_Background</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-09-23_Astronomy_Picture_of_the_Day_for_Mac_OSX_Desktop_Background</wiki:diff>
<category>Mac</category>
<category>Desktop</category>
<category>APOD</category>
<category>Perl</category>
</item>

<item>
<title>Random Subsector Generator</title>
<link>http://alexschroeder.ch/wiki/2009-09-11_Random_Subsector_Generator</link>
<guid>http://alexschroeder.ch/wiki/2009-09-11_Random_Subsector_Generator</guid>
<description>&lt;p&gt;Once I had the &lt;a class="local" href="http://alexschroeder.ch/wiki/2009-09-11_Elite_Names"&gt;name generator&lt;/a&gt;, I was ready to write up the rest of the script. The &lt;a class="url http outside" href="http://alexschroeder.ch/uwp-generator"&gt;subsector UWP list generator&lt;/a&gt; will also compute the temperature for internal purposes, but doesn&amp;#x2019;t print it because it&amp;#x2019;s not part of the &lt;a class="url http outside" href="http://www.travellermap.com/formats.htm"&gt;UWP&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I decided that systems with code Amber and piratets are considered code Red. The rules just say that &amp;#x201c;Red codes are given out at the discretion of the Referee.&amp;#x201d;&lt;/p&gt;&lt;p&gt;The cool thing is that you can paste &amp;amp; copy the resulting list into the &lt;a class="local" href="http://alexschroeder.ch/wiki/2009-09-11_Traveller_Map_Based_on_UWP"&gt;map generator&lt;/a&gt; and generate the map to go along with it.&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Traveller"&gt;Traveller&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Traveller"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=RPG"&gt;RPG&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/RPG"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Generator"&gt;Generator&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Generator"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Perl"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Fri, 11 Sep 2009 23:28:36 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-09-11_Random_Subsector_Generator</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>2</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-09-11_Random_Subsector_Generator</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-09-11_Random_Subsector_Generator</wiki:diff>
<category>Traveller</category>
<category>RPG</category>
<category>Generator</category>
<category>Perl</category>
</item>

<item>
<title>Strange Perl Issue</title>
<link>http://alexschroeder.ch/wiki/2009-08-03_Strange_Perl_Issue</link>
<guid>http://alexschroeder.ch/wiki/2009-08-03_Strange_Perl_Issue</guid>
<description>&lt;p&gt;Today I had to make the following change to &lt;a class="local" href="http://alexschroeder.ch/wiki/Oddmuse"&gt;Oddmuse&lt;/a&gt; because that fixes an image upload issue on my dad&amp;#x2019;s blog. What&amp;#x2019;s going on? He&amp;#x2019;s using the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Apache/2.2.3 (Debian) DAV/2 SVN/1.4.2 mod_jk/1.2.18 mod_ssl/2.2.3 OpenSSL/0.9.8c mod_wsgi/2.3 Python/2.5&lt;/li&gt;&lt;li&gt;Perl v5.8.8&lt;/li&gt;&lt;li&gt;CGI: 3.15&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Any ideas? The net result was that &lt;code&gt;&amp;lt;$file&amp;gt;&lt;/code&gt; resulted in no content if run within the eval block.&lt;/p&gt;&lt;pre class="real"&gt;*** wiki.pl.~1.925.~	Fri Jul  3 11:23:01 2009
--- wiki.pl	Tue Aug  4 00:20:26 2009
***************
*** 3548,3554 ****
      $type = $q-&amp;gt;uploadInfo($filename)-&amp;gt;{'Content-Type'};
      ReportError(T('Browser reports no file type.'), '415 UNSUPPORTED MEDIA TYPE') unless $type;
      local $/ = undef;   # Read complete files
!     eval { require MIME::Base64; $_ = MIME::Base64::encode(&amp;lt;$file&amp;gt;) };
      $string = '#FILE ' . $type . "\n" . $_;
    } else {
      $string = AddComment($old, $comment) if $comment;
--- 3548,3555 ----
      $type = $q-&amp;gt;uploadInfo($filename)-&amp;gt;{'Content-Type'};
      ReportError(T('Browser reports no file type.'), '415 UNSUPPORTED MEDIA TYPE') unless $type;
      local $/ = undef;   # Read complete files
!     my $content = &amp;lt;$file&amp;gt;; # Apparently we cannot count on &amp;lt;$file&amp;gt; to always work within the eval!?
!     eval { require MIME::Base64; $_ = MIME::Base64::encode($content) };
      $string = '#FILE ' . $type . "\n" . $_;
    } else {
      $string = AddComment($old, $comment) if $comment;&lt;/pre&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Oddmuse"&gt;Oddmuse&lt;/a&gt; &lt;a class="feed tag" title="Feed für diesen Tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Oddmuse"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Mon, 03 Aug 2009 22:29:18 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-08-03_Strange_Perl_Issue</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>new</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>1</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-08-03_Strange_Perl_Issue</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-08-03_Strange_Perl_Issue</wiki:diff>
<category>Perl</category>
<category>Oddmuse</category>
</item>

<item>
<title>Spam Makes Sending Mail Harder</title>
<link>http://alexschroeder.ch/wiki/2009-06-06_Spam_Makes_Sending_Mail_Harder</link>
<guid>http://alexschroeder.ch/wiki/2009-06-06_Spam_Makes_Sending_Mail_Harder</guid>
<description>&lt;p&gt;Here I am trying to send mail using some Perl module. But most of them seem to be written for the last millenium. They work best with a local SMTP host. For my own needs, that no longer works. The webhost doesn&amp;#x2019;t have a sendmail binary available. The SMTP hosts I can reach require SSL and TLS authentication. Now I&amp;#x2019;m slowly digging into MIME::Entity, Mail::Internet, Mail::Mailer, Net::SMTP, Net::SMTP::SSL, Net::SMTP::TLS… &lt;img class="smiley" src="http://www.emacswiki.org/pics/sad.png" alt=":(" /&gt; &lt;img class="smiley" src="http://www.emacswiki.org/pics/sucks.png" alt="sucks" /&gt;&lt;/p&gt;&lt;p&gt;After experimenting with the four or five mail accounts I have access to, I was finally able to get the following to work:&lt;/p&gt;&lt;pre class="real"&gt;my $from = 'kensanata@gmail.com';
my $to = $from;
my $host = 'mail.epfarms.org';
my $user = 'alex';
my $password = '*secret*';

use MIME::Entity;
my $mail = new MIME::Entity-&amp;gt;build(To =&amp;gt; $to,
				   From =&amp;gt; $from,
				   Subject =&amp;gt; 'test',
				   Path =&amp;gt; '/Users/alex/test.html',
				   Type =&amp;gt; 'text/html');

use Net::SMTP::TLS;
my $smtp = Net::SMTP::TLS-&amp;gt;new($host,
			       User =&amp;gt; $user,
			       Password =&amp;gt; $password,
			       Debug =&amp;gt; 1);
$smtp-&amp;gt;mail($from); # sender
$smtp-&amp;gt;to($to);     # recipient
$smtp-&amp;gt;data;
$smtp-&amp;gt;datasend($mail-&amp;gt;stringify);
$smtp-&amp;gt;dataend;
$smtp-&amp;gt;quit;&lt;/pre&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/Perl"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://alexschroeder.ch/wiki?action=tag;id=SMTP"&gt;SMTP&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://alexschroeder.ch/wiki/feed/full/SMTP"&gt;&lt;img src="http://alexschroeder.ch/pics/rss.png" alt="RSS" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Sat, 06 Jun 2009 14:49:45 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-06-06_Spam_Makes_Sending_Mail_Harder</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>2</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-06-06_Spam_Makes_Sending_Mail_Harder</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-06-06_Spam_Makes_Sending_Mail_Harder</wiki:diff>
<category>Perl</category>
<category>SMTP</category>
</item>

<item>
<title>Oddmuse Mail Subscription Dubious</title>
<link>http://alexschroeder.ch/wiki/2009-05-16_Oddmuse_Mail_Subscription_Dubious</link>
<guid>http://alexschroeder.ch/wiki/2009-05-16_Oddmuse_Mail_Subscription_Dubious</guid>
<description>&lt;p&gt;I&amp;#x2019;m thinking about adding mail subscription to Oddmuse. I used to oppose this, claiming that people should use &lt;a class="local" href="http://alexschroeder.ch/wiki/rss2email"&gt;rss2email&lt;/a&gt; and similar feed subscriptions as a replacement. I changed my mind when I joined the &lt;a class="near" title="Names" href="http://rpgbloggers.blogspot.com/"&gt;RPG Bloggers&lt;/a&gt;. I read a lot of posts from blogs I&amp;#x2019;m not subscribed to. When I leave a comment, I&amp;#x2019;m interested in getting notified of replies to this one post only. Email just works.&lt;/p&gt;&lt;p&gt;&lt;h2&gt;Plan&lt;/h2&gt;&lt;/p&gt;&lt;p&gt;Visitors can add their email address and click a checkbox to subscribe to changes when they edit a page. The requirement to successfully edit a page acts as a defense mechanism against spammers and vandals (&lt;a class="near" title="Community" href="http://www.communitywiki.org/cw/SoftSecurity"&gt;SoftSecurity&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Email addresses are stored in a file. Each mail contains an unsubscribe link, and from there users can see (and unsubscribe from) all other pages they are subscribed to. The link contains a hash of the email address which prevents others from guessing what email addresses have subscriptions.&lt;/p&gt;&lt;p&gt;There is also an admin interface that shows which email addresses are subscribed to which pages, allowing the easy removal of email addresses from the database.&lt;/p&gt;&lt;p&gt;&lt;h2&gt;Perl&lt;/h2&gt;&lt;/p&gt;&lt;p&gt;The problem was that on my host, there is no C compiler, so I was unable to install Email::Sender. The web processes also run in an environment without access to sendmail. Net::SMTP does not support &lt;a class="near" title="Wikipedia" href="http://en.wikipedia.org/wiki/Transport Layer Security"&gt;Transport Layer Security&lt;/a&gt; (TLS). Googling around I found a &amp;#x201c;Simple SMTP client with STARTTLS and AUTH support&amp;#x201d; by Michal Ludvig: &lt;a class="url http outside" href="http://www.logix.cz/michal/devel/smtp/"&gt;Command line SMTP client&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;On my Mac OS 10.4 system at home, I wasted a lot of time trying to install Bundle::CPAN. Gaaah! Some dependencies were not automatic, but a few good invocations of &lt;code&gt;reports&lt;/code&gt; on the CPAN command-line followed by manual installation of the missing package did the job.&lt;/p&gt;&lt;p&gt;I also needed to install IO::Socket::SSL with all its dependencies. Yuck! And it turns out that there is a dependency on Net::SSLeay, which needs a C compiler to build.&lt;/p&gt;&lt;p&gt;Thus, the command-line script will also not do for me!&lt;/p&gt;&lt;p&gt;In the end, I think I will ask them to install libemail-send-perl and libnet-smtp-ssl-perl for Email::Send and Net::SMTP::SSL; there is also Email::Send::Gmail but no corresponding Debian package. We&amp;#x2019;ll see; I might get it to work without.&lt;/p&gt;&lt;p&gt;Anyway, I decided to invest some time into coding an Oddmuse extension. I was all enthusiastic about it. But now I spent hours fooling around with Perl installations and test programs, I think I will stop it now and read a book or something.&lt;/p&gt;&lt;p&gt;Bummer.&lt;/p&gt;&lt;p&gt;&lt;h2&gt;Oddmuse Sends No Email&lt;/h2&gt;&lt;/p&gt;&lt;p&gt;Thinking about it some more, sending mail after an edit might work for comment submission on comment pages, but it will never work for edits to ordinary pages. So right now I&amp;#x2019;m working on code that lets me subscribe and unsubscribe from pages, and a computer-readable output of said data. Then I will use a cron-job to send the appropriate emails.&lt;/p&gt;&lt;p&gt;Tags: &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Oddmuse"&gt;Oddmuse&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Oddmuse"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Perl"&gt;Perl&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Perl"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt; &lt;a class="outside tag" title="Tag" rel="tag" href="http://www.emacswiki.org/alex?action=tag;id=Mail"&gt;Mail&lt;/a&gt; &lt;a class="feed tag" title="Feed for this tag" rel="feed" href="http://www.emacswiki.org/alex?action=journal;full=1;search=tag:Mail"&gt;&lt;img src="http://www.emacswiki.org/alex/pics/rss.png" /&gt;&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Sat, 16 May 2009 23:51:30 GMT</pubDate>
<comments>http://alexschroeder.ch/wiki/Comments_on_2009-05-16_Oddmuse_Mail_Subscription_Dubious</comments>
<dc:contributor>AlexSchroeder</dc:contributor>
<wiki:status>updated</wiki:status>
<wiki:importance>major</wiki:importance>
<wiki:version>2</wiki:version>
<wiki:history>http://alexschroeder.ch/wiki?action=history;id=2009-05-16_Oddmuse_Mail_Subscription_Dubious</wiki:history>
<wiki:diff>http://alexschroeder.ch/wiki?action=browse;diff=1;id=2009-05-16_Oddmuse_Mail_Subscription_Dubious</wiki:diff>
<category>Oddmuse</category>
<category>Perl</category>
<category>Mail</category>
</item>
</channel>
</rss>
