tag:blogger.com,1999:blog-21180584550755562592024-02-20T12:02:53.842-08:00The Perl Hacker PainterA blog about Perl, written from an Artist's perspectiveUnknownnoreply@blogger.comBlogger25125tag:blogger.com,1999:blog-2118058455075556259.post-82305365822448779662016-08-09T12:02:00.001-07:002016-08-09T12:02:41.285-07:00Dada Mail v9.6.0 Relased - security enhancementsGoodness, where does the time go?<br />
<br />
The last time I wrote on this blog about Dada Mail we were on v9.0.0 - now we're 6 versions past that.<br />
<br />
Here's the <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dada_announce/20160804005232/">announcement of the release</a> - please subscribe to the mailing list if you're interested in following along,<br />
<br />
Much of what I do in this project is make complicated things easy to use. <a href="http://blog.dadamailproject.com/2016/08/02/dada-mails-subscription-abuse-prevention-systems/">Here's a rundown of many of the security enhancements and abuse protection</a> things just for the subscription process. It's not required that my users know what all this is, but everything here is enabled by default, and works without any needed bother. Not an easy task!, but makes me sleep a little better at night.<br />
<br />
As well as the email list, you can find the project on <a href="https://github.com/justingit/dada-mail/">github</a>, <a href="https://twitter.com/dadamail">twitter</a>, and <a href="https://www.youtube.com/user/leaddadaist">youtube</a> - the latter of which i post screencasts on how to use the app - installation should be pretty simple, as illustrated in this screencast,<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/s5vTHUpC-n8/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/s5vTHUpC-n8?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
<br />
Give it a go! As Perl projects go, I think it's worth checking out (biased, obviously!) <br />
<br />
<br />Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-2118058455075556259.post-86133300256889009012015-12-11T15:06:00.002-08:002015-12-11T15:06:27.510-08:00Dada Mail v9 ReleasedThe latest major release of Dada Mail has been released. <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dada_announce/20151208231207/">Version Nine! </a><br />
<br />
<a href="http://dadamailproject.com/">Dada Mail </a>is an email mailing list manager, written in Perl. Usually in my posts, I go over all the cool things I was able to get accomplished, because of some neat Perl module or technique.<br />
<br />
The last major release focuses on redesigning the backend of Dada Mail, and adding support to run it under PSGI/Plack, while also maintaining the ability to run it under CGI. For that, I moved over to <a href="https://metacpan.org/pod/CGI::Application">CGI::Application</a>.<br />
<br />
This release focuses almost explicitly on the front end design and layout - and for that, I utilized the <a href="http://foundation.zurb.com/">Zurb Foundation Framework</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWmjQ1A02mOq-GxG3mrqsMTOmOrOV-kDGslYwbyfL4lfvhHhNNe_EWqjLTZMxKikdQPjcrgqSBUJciheEuCMY5KzaiMNWp9BnLYbBIfJKdguO4ZK9vZkKwmUE226gBPVFodjxmFnyTlXs/s1600/zurb.jpg" /><span id="goog_511058776"></span><span id="goog_511058777"></span></div>
<br />I couldn't have imagined how much work moving to Foundation would have taken, when I started. Sling a few <div>'s here and there - right?<br />
<br />
Well, wrong - and it wasn't Foundation's fault. Although there is a learning curve to working with their flavor of HTML markup, and a slightly tougher grade to learn their SCSS workflow (and setting up the environment is a little... <i>obtuse</i>) - the real culprit is that the Dada Mail project really pretty large.<br />
<br />
Dada Mail has over 300 separate template files that make up all its views, and the project itself was started in 1999. Let's say you need to make a complicated layout of form fields and such. What do you use? <br />
<br />Well, in 1999 you use tables. And if it ain't broke, why fix it? So tables it was for a lot of the forms that the UI used for all those preference screens. That's fine and good, until you want your app to work well on a mobile phone's browser. Now, everything is legitimately <b>broken</b>, because a lot of the design has fixed widths and isn't very responsive. <br />
<br />
To fix a lot of the UI problems meant replacing the table-based layout with Foundation's Grid System. A lot of my forms had secondary and even tertiary form elements, that needed to be shown underneith other form elements, so that the user knows they're somehow related. After a bit if wrangling, Foundation made this realistic to do.<br />
<br />
Here's an example of a somewhat complicated part of form for changing the template of your mailing lists message,<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFXE8-yRrWnqazGa1mW1TVdHjiKdjpu4uOQwbju9tXNrUtmdKzOqtF_9yjKbFTYDKXqSsVYJ8ftHw42V4AkGBMk48GL0h6SS7eIpNhEpiLN60q9PAsJTUsmbZE2bCK5sZyd_URivdXmns/s1600/Appearance_%25C2%25BB_Email_Message_Templates_-_Justin_s_Test%25E2%2580%2594List_-_Pro_Dada_-_2015-12-11_16.03.03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFXE8-yRrWnqazGa1mW1TVdHjiKdjpu4uOQwbju9tXNrUtmdKzOqtF_9yjKbFTYDKXqSsVYJ8ftHw42V4AkGBMk48GL0h6SS7eIpNhEpiLN60q9PAsJTUsmbZE2bCK5sZyd_URivdXmns/s640/Appearance_%25C2%25BB_Email_Message_Templates_-_Justin_s_Test%25E2%2580%2594List_-_Pro_Dada_-_2015-12-11_16.03.03.png" width="640" /></a></div>
<br />
<br />
<br />
It's pretty phenomenal that this can now be done, with a having to revert to using a table-based layout. The diff file for this release was over 100,000 lines long, which goes to show you just how much HTML I've been working with for the last few months. I have long since separated the HTML out of Dada Mail, so almost nothing had to be modified in the Perl side of things at all, to get things runnin'. For templates, I've been using <a href="https://metacpan.org/pod/HTML::Template">HTML::Template</a> (and friends) since forever, and probably will keep on chugging - with the most obvious successor being Template-Toolkit, if the need ever arises. I'm not sure if that makes sense for me now, but we'll see what the future holds.<br />
<br />
<br />
Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-2118058455075556259.post-77232861156633194042015-08-06T14:05:00.001-07:002015-08-06T14:05:14.607-07:00Dada Mail Screencasts!<a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dada_announce/20150731214136/">Dada Mail v8.4.0 was recently released</a> (hurray!) One of the ways I've been experimenting with showing people all the cool features of Dada Mail is by doing screencasts - below are some of the screencasts I've recently put together.<br />
<br />
<b>Dada Mail v8 Quick Install Guide: </b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/cRGT2QafnrY/0.jpg" src="https://www.youtube.com/embed/cRGT2QafnrY?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
This screencast is meant to showcase just how easy it is to install Dada Mail, using the web-based installer. Dada Mail does have a <a href="http://dadamailproject.com/support/d/install_dada_mail_cl.pod.html">CLI installer</a>, as well - that's the way to go, if you want to automate an install/upgrade, as well as to take advantage of Dada Mail's PSGI/Plack support. <br />
<br />
<b>Importing Addresses into Dada Mail: </b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/cg6KFZJRYoA/0.jpg" src="https://www.youtube.com/embed/cg6KFZJRYoA?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
Many people using Dada Mail - especially for discussion lists, are moving from a previous system (like Mailman) - this screencast was created to show how easy it is to import an already-created list over.<br />
<br /><b>Magic User Templates</b><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Op2UZXjzuns/0.jpg" src="https://www.youtube.com/embed/Op2UZXjzuns?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />This screencast shows how to change the layout of Dada Mail to match your own website - it using HTML::Tree under the hood, <a href="http://perlhackerpainter.blogspot.com/2015/06/using-htmltree-to-create-magic.html">which I wrote about, recently. </a><br />
<br />
<b>Dada Mail Scheduled Mailings: </b> <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/amWFj8NzpLQ/0.jpg" src="https://www.youtube.com/embed/amWFj8NzpLQ?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
This screencast showcases a few mature features in Dada Mail, including Sending a Webpage (whole or in part), as well as setting up a recurring scheduled mass mailing, that only sends when the source content has changed. Neat stuff.<br />
<br />
Give <a href="http://dadamailproject.com/">Dada Mail</a> a spin, if you haven't already - it's a long running, and fairly popular Perl web app. I would say one of the most popular Perl-based web app targeted for regular folks (as opposed to Perl hackers) Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-30573226030370596052015-06-30T09:58:00.002-07:002015-06-30T09:58:34.429-07:00Using HTML::Tree to create magic<a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dada_announce/20150629221814/">Dada Mail v8.3 was recently released. </a>Dada Mail itself is a mailing list manager written in Perl. It's a project I've been working on since 1999(!) - lots of blood/sweat/tears. It's somewhat of a mix between Mailman (or Majordomo, if you remember that app, which I initially went out to inadvertently replace!), and one of the big email marketing services, like Constant Contact or MailChimp.<br />
<br />
Difference to those services, is that you run it on your own server/hosting account. The system requirements are minimal (really), so a cheap cPanel-based shared hosting on Bluehost or whatever will work just fine.<br />
<br />
It has support to hook up with Amazon SES for mail sending, giving you a very competitive platform to send mass mailings to your announcement list or discussion list at a really good price. If you want more performance, you can run it as a PSGI app - full support to run it under Plack/PSGI, or running as a FastCGI script without Plack (mod_fcgi?), or as a plain CGI script, even. Dada Mail tries to be flexible. You won't need root access to install - it comes with its <a href="http://dadamailproject.com/d/install_dada_mail.pod.html">own web-based installer.</a> Just upload the distro and a helper script, and away you go. <br />
<br />
One of the newer features of the app is called, <a href="http://dadamailproject.com/d/features-magic_user_templates.pod.html">Magic User Templates</a>. This feature allows someone with very little experience with manipulating HTML code to integrate Dada Mail into their already existing site. It does this by basing it's own layout and design off of an already created page - say: the homepage to your own website.<br />
<br />
Magic User Templates fetch this via a URL, and then places its own content between a tag, it finds via a css selector that you specify. Pretty easy for the user, and solves the problem I've been having of people wanting to brand the app to match their site, but <i>not</i> wanting to dive into their site's HTML the HTML of the Dada Mail's templates, and then learning how the templating language Dada Mail works (HTML::Template, basically). That's a big barrier to entry, when you just want something branded.<br />
<br />
"Integration with Wordpress" is maybe my #1 feature request, but it's a nonsensical thing to me - what exactly does that mean? If it means: "I want Dada Mail to look like the rest of my site", then Magic Templates are the answer.<br />
<br />
To do all this manipulation, I've taken advantage of the excellent <a href="https://metacpan.org/release/HTML-Tree">HTML::Tree</a> CPAN distribution, which can read in the HTML pretty well, and give a tree-based interface to the HTML the page is made up of. Then you can fairly successfully output the HTML back.<br />
<br />
It does have some shortcomings, as it has a hard time with HTML5 tags. There's a bug opened up about it (which, I now can't track down - believe it has to do with HTML::Parser?), but there's not been a lot of work to fix it, as the maintainer wants a <i>correct</i> fix, and not a <i>hack</i>.<br />
<br />
One solution is to use the <a href="https://metacpan.org/pod/HTML::TreeBuilder::LibXML">HTML::TreeBuilder::LibXML</a> module instead of HTML::TreeBuilder, but it comes with its own silent dragons - the docs are just so minimal, it's difficult to gauge what the heck it actually to does and what methods are now unsupported.<br />
<br />
I gather the lack of docs is in direct inverse to the brilliance of the module author, and that's a weakness of being just a regular ol' joe (like me). Regardless, that will be the future of where I go with this, but for now, HTML::Tree is working great.<br />
<br />
<a href="https://github.com/justingit/dada-mail/blob/fbc874091e9ffba171bbbc744b0c8de8ab89b134/dada/DADA/Template/HTML.pm#L368-L537">Here's the code I came up with</a>. Hopefully the code is very straightforward, readable, and holds no tricks whatsoever.<br />
<br />
My coding is fairly straightforward for many reasons: I like no-nonsense stuff, and this is actively maintained code - it's a living project for the last 15 years! One demerit I'll give it though, is that it is a long, long sub. Someone much cleverer than I could take this down a bit. <br />
<br />
HTML::Tree (and friends) provide just the right amount of API to do the job and do it well (although it took a little bit to figure out the right incantation). To work around some of the HTML 5 weaknesses of HTML::TreeBuilder, I call it with the following arguments:<br />
<br />
<pre><code>
my $root = HTML::TreeBuilder->new(
ignore_unknown => 0,
no_space_compacting => 1,
store_comments => 1,
); </code></pre>
<br />
For the majority of the cases, that works well. You may notice that the code is also written very defensively. Since Dada Mail is released as an app you're supposed to simply upload and run (Basically), I can't promise that HTML::Tree and friends are going to be available, so this entire feature has to be optional, and not cause the entire app to break. Rather, <a href="http://dadamailproject.com/d/FAQ-installing_CPAN_Perl_modules.pod.html">I give directions on how to install the missing CPAN modules</a>, so that a motivated user can do that part of everything themselves.<br />
<br />
I've also gotten into the habit of returning such defensive subs with 3 values: a status of if it worked, a hashref of errors to describe what didn't work, and the returned string, which is also set to undef if things didn't pan out right. With that, I can then fallback to something else, if the sub didn't return what I need. The idea is that something needs to work, since a template has to be returned to be used, and it's not acceptable to have something like this break, which would break the entire app. This is a great example of why: since we're relying on an outside resource (the URL to the webpage), that resource could be gone, or the details of it (the css selector in the HTML) could be changed, rendering our configuration outdated.<br />
<br />
What do you do? Throw an error and break the app, or return what the problem is, and try to describe would could be wrong, so that you can reapply the Magic Template in a more correct manner, later? For me, the correct answer is to do the latter. This is a consumer focused app, and people just want to get the job done, without having the app break in surprising ways.<br />
<br />
<br />
<br />
<br />Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-2118058455075556259.post-27444666844507219852015-04-28T15:15:00.004-07:002015-04-28T15:15:31.748-07:00Dada Mail Eight Released<a href="http://dadamailproject.com/">Dada Mail v8 was recently released </a> - Dada Mail is a mailing list manager that works with announcement-only and discussion lists, public and private lists and a ton of things in between. It's written in Perl and runs on practically anything you can throw at it (as long is it's Unix-like)<br />
<br />
The big ta-do with v8 is that Dada Mail supports being run under FastCGI and Plack/PSGI, when before it was only able to run under CGI. That's a big level up. Thankfully, because of the Perl community, porting a project that began in <i>1999</i> and has been growing quite organically since then wasn't terribly impossible. For the rest of this post, I'll be going into some of approaches I used, to make this happen, with the <strike>minimal amount of work</strike> maximum amount of laziness, impatience and hubris.<br />
<h2>
CGI::Application</h2>
Fortunately or unfortunately, one of the constraints of adding support for Plack/PSGI is that CGI support still has to be kept: meaning you can throw up the app via FTP, run an install script, give it some parameters like database creds. and be off to the races.<br />
<br />
The vast majority of installs of Dada Mail are done on pretty simple, cPanel-based (also a Perl company) shared hosting accounts. Small business use Dada Mail to keep in contact with their customers. Churches and private groups (think doctors and lawyers that want to talk shop) run off of it. With Dada Mail's support for third party email services like Amazon SES, this is actually a pretty realistic situation. Shared host companies usually have pretty terrible shared host mail servers, especially if you're running a very big/busy list; Amazon SES (and friends) work much better.<br />
<br />
This means using a framework like Catalyst or Mojolicious is currently not looking so hot. The minimum Perl version being targeted is v5.10.1 (and even that isn't available in many shared hosts - tragic!)<br />
<br />
But, the venerable <a href="https://metacpan.org/pod/CGI::Application">CGI::Application</a> framework looks great! Since it already walks the line of easily supporting both CGI apps (which it was built to do!) and PSGI/Plack apps (which it has since been given support for!).<br />
<br />
The main difference with writing a CGI app for CGI::Application, is that you return a string for the body of your page in each method, and set parameters for any headers you would also like to send. CGI::App does the actual printing to (say) STDOUT for you. This small amount of encapsulation helps keep your app a bit tidier than without it, since you're not print()ing whilly-nilly everywhere. <br />
<br />
So, the first step, if you were to migrate to CGI::App, is to find all those print statements, and get rid of them, only returning the data you want to show. That's an easy step, but can take a little while to find every instance of this happening.<br />
<h3>
Run Modes</h3>
CGI::App has the idea of run modes - run modes can be thought of each screen of your app. You probably have a default run mode. For Dada Mail there's a list page run mode, and admin login run mode, a send out a mass mailing run mode, etc. <br />
<br />
Thankfully, the previous version of Dada Mail had a similar idea, with code right out of the <a href="http://www.amazon.com/Perl-Cookbook-Second-Tom-Christiansen/dp/0596003137/ref=sr_1_1/180-8223782-2462609?s=books&ie=UTF8&qid=1430259175&sr=1-1&keywords=perl+cookbook+3rd+edition">Perl Cookbook:</a><br />
<br />
<code></code><br />
<pre><code>sub run {
#external (mostly..) functions called from the web browser)
# a few things this program can do.... :)
my %Mode = (
'default' => \&default,
'subscribe' => \&subscribe,
# a whole bunch of other subs
);
if ($flavor) {
if ( exists( $Mode{$flavor} ) ) {
$Mode{$flavor}->(); #call the correct subroutine
}
else {
&default;
}
}
else {
&default;
}
}
</code></pre>
<br />
Porting this to CGI was simple enough, in its setup() method. In App.pm: <br />
<pre><code>
sub setup {
my $self = shift;
$self->start_mode('default');
$self->mode_param('flavor');
$self->error_mode('yikes');
$self->run_modes(
'default' => \&default,
'subscribe' => \&subscribe,
# Many, many more,
);
}
</code></pre>
<code>
</code>
<br />
CGI::App does have CGI::App::Dispatch to help with mapping PATH_INFO information to various resources served up by your app. I wasn't keen on porting Dada Mail's dispatch-ish stuff to this - yet. It seemed like a great way to break current ways we're doing things, AND the current way of doing things is 15 years of messiness. <br />
<br />
Instead, I modified the parameters you pass to CGI::App, before it's given the param()-compatible object (in our case: CGI.pm). in the harness script (in CGI::App parlance: app.cgi):<br />
<br />
<code></code><br />
<pre><code>
use CGI;
# DADA::App is our CGI::App
use DADA::App;</code></pre>
<pre><code> </code></pre>
<pre><code># DADA::App::Dispatch changes around paramaters, and puts things</code></pre>
<pre><code># form the PATH_INFO env. var. into param()s: </code></pre>
<pre><code>use DADA::App::Dispatch;
my $d = DADA::App::Dispatch->new;
my $q = new CGI;
$q = $d->prepare_cgi_obj($q);
my $dadamail = new DADA::App( QUERY => $q, );
$dadamail->run();
</code></pre>
<br />
<br />
Here, prepare_cgi_obj() just takes the CGI.pm object, reads the PATH_INFO and stuffs values into various parameters, much like CGI::APP::Dispatch, but without the need for me to rewrite everything - we just encapsulate it into its own method. When I'm ready, I could move over to CGI::App::Dispatch (or not! Thus the beauty of CGI::App).<br />
<br />
Once that's all figured out, I'm still left with a CGI script, rather than a Plack/PSGI script. My solution is to ship with multiple version of this harness script, and run a different harness script, depending on the environment I want to run under. The PSGI/Plack harness script looks like this:<br />
<br />
<code></code><br />
<pre><code>use CGI::PSGI;
use DADA::App;
use DADA::App::Dispatch;
my $handler = sub {
my $env = shift;
require Data::Dumper;
my $d = DADA::App::Dispatch->new;
my $q = CGI::PSGI->new($env);
my $q = $d->prepare_cgi_obj($q);
my $webapp = DADA::App->new({ QUERY => $q });
$webapp->run_as_psgi;
};
</code></pre>
<br />
Dada Mail already comes with a web-based installer, which works great for installing Dada Mail as a CGI script, but would need a little more work to work under Plack/PSGI. It didn't seem really worth it to add support for that, so I instead gave Dada Mail's current installer support for being run via the command line, so you can install/configure Dada Mail for Plack/PSGI, right before you run the, plackup command, which is a much nicer workflow.<br />
<br />
In a nutshell, that's all it took to take a very mature codebase and have it run under Plack/PSGI, as well as still keep support for CGI. There's some details I've skipped, like making sure database connections are persistent (I used a singleton module to keep the connection cached and persistent) <br />
<br />
Here's some more meta on this dramatic change in the back end of things:<br />
<br />
Dada Mail is on Github, <a href="https://github.com/justingit/dada-mail/compare/v7_4_1-stable_2015_02_20...v8_0_0-stable_2015_03_31">so you can see the difference between the pre and post CGI::App-based Dada Mail.</a> There's not too many new features, but we're hoping all this new organization helps with keeping the app growing well into the future: <br />
<blockquote class="tr_bq">
Showing
<b>
281 changed files</b>, with
<strong>38,717 additions</strong>
and <strong>31,998 deletions</strong>.</blockquote>
Here's how the installer works <a href="http://dadamailproject.com/d/install_dada_mail.pod.html">for web-based (for CGI installs),</a> as well as <a href="http://dadamailproject.com/d/install_dada_mail_cl.pod.html">on the command line (for PSGI/Plack)</a><br />
<br />
More on <a href="http://dadamailproject.com/d/features-psgi_support.pod.html">PSGI/Plack support with Dada Mail</a><br />
<br />
Please give <a href="http://dadamailproject.com/">Dada Mail</a> a spin, the next time you have the need to set up a mailing list. Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-2118058455075556259.post-22034671625894527632014-04-08T19:09:00.004-07:002014-04-08T19:09:50.735-07:00Dada Mail Seven Released! Rejoice!I've just shipped v7 of <a href="http://dadamailproject.com/">Dada Mail</a>! Dada Mail is a web-based mailing list manager, written in Perl. It's a project I started way back in 1999 - one of those, "started in my dorm room" types of projects.<br />
<br />
I'm currently catching my breath from the big push to finally Ship, but it feels good to get it all done. <br />
<br />
One of the more interesting (to me) aspects of this release was to finally ship a PDF manual. I write most of the docs in Plain Old Documentation (with a little HTML sprinkled in), which is then turned into HTML, which is then! then turned into a PDF book. I've been wrestling with how best to do with, but it turned out just using HTMLDoc directly was the best way to go about things. A little (minor) futzing with my POD/HTML to make the table of contents pretty is all I needed to do. I already and still have an HTML version of the manual online for people to utilize, but now people can download it and read it on their favorite device, which a lot of my users have been clamoring for. <br />
<br />
I think I surprised myself to know that the book surprised 300 pages by a wide margin! That's a lot of writing! It gives me a lot of confidence to write another book, since I can't tell myself, "<i>Well, books are long! And there's no way you'll ever write that much!</i>" . I can now tell myself, "<i>Whoops! You somewhat mistakenly already have! DO IT AGAIN!</i>"<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-29918986831316454342013-10-16T11:33:00.002-07:002013-10-16T11:33:08.818-07:00Email::Valid PeculiaritiesOver here at <a href="http://dadamailproject.com/">Dada Mail</a>, we do a lot of verification of email addresses when confirming subscriptions. Is the form of the email correct? Has this address been used to try to subscribe with before? Has the user themselves confirmed their subscription? What happens when there's an error? There's a lot to it (sadly) and if something in one of these steps goes wrong, a subscription doesn't happen, or worse yet, a mailing list is tarnished with not-so-valid addresses. This little tale is about <i>invalid</i> in form addresses getting on people's mailing lists.<br />
<br />
A user posted on the <a href="http://dadamailproject.com/support/boards/">Dada Mail support forums</a>: <i>"There's an address with a space in it, that's entered my list! It's causing problems with delivery of the ENTIRE list? How did that happen?"</i><br />
<br />
A lot of the time developing a very complicated piece of software is supporting it (I think, anyways). When a question like this comes down the tubes, I have no great answer, except it must have been an outside thing. So I ask, <i>"Was the address added directly into the backend?"</i> That's something that happens from time to time, although there are many pitfalls: importing data can be done incorrectly - and even if it's done correctly once, the design of the backend can change, and then it's not done correctly anymore.<br />
<br />
That's why, if it's an option, it's a good idea to use the API that presented to the developer, rather than try to retinker it, yourself. <br />
<br />
When the user replied back with, <i>"Nope!"</i> I knew I was really stuck. <i>"But I have tests!"</i> I protested to my Macbook Pro. <i>"Coverage!"</i> <i>"I didn't roll my own email validator!" "I did everything you're supposed to do!" </i><br />
<br />
<i> </i>So, current tests be-damned, I had to start from square one: Attempt to recreate the problem, in the simplest way I could. So, I tried to join a list, with an address with a space in it, like this:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">myaddress@example .com</span><br />
<br />
And, wouldn't you know it, the app took the address like nothing was wrong. Now, totally believing my user, but being in total <i>disbelief</i> myself, it was time to hit the code. We use <a href="https://metacpan.org/module/Email::Valid"><span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span></a> in Dada Mail, to test the validity of an email address, like so:<br />
<br />
<br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
my $address = 'someone@example.com';
if(Email::Valid->address($address)){
print "Valid!";
}
else {
print "NOPE!";
} </code></pre>
<pre><code># prints, Valid! </code></pre>
<br />
<br />
<b>This is wrong. </b>Observe:<br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
my $address = 'someone@example .com'; # notice the space!
if(Email::Valid->address($address)){
print "Valid!";
}
else {
print "NOPE!";
}
# Prints, Valid!</code></pre>
<br />
And, there's my problem, in a pretty simple case.<br />
<br />
So, what's going on? Basically my code had <b>assumed</b> that <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span>'s address method returned a boolean value. It does not. From Email::Valid's docs (<b>emphasis</b> is mine):<br />
<blockquote class="tr_bq">
This is the primary method which determines whether an email address
is valid. It's behavior is modified by the values of mxcheck(),
tldcheck(), local_rules(), fqdn(), and fudge(). If the address passes
all checks, the (<b>possibly modified</b>) address is returned as a string. <b>
Otherwise, the undefined value is returned</b>. In a list context, the
method also returns an instance of the Mail::Address class representing
the email address.</blockquote>
Big difference! So let's try that code snippet, again:<br />
<br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
my $address = 'someone@example .com'; # notice the space!
my $validated_address = undef;
if($validated_address = Email::Valid->address($address)){
print "Valid!: $validated_address";
}
else {
print "NOPE!";
}
# prints, Valid!: someone@example.com
</code></pre>
<br />
Ah-ha: <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> will take it upon itself to modify the email address for you - but only in certain circumstances - spaces in <i>certain</i> places of the address. So, this still returns <span style="font-family: "Courier New",Courier,monospace;">undef</span>: <br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
my $address = 'some one@example.com'; # notice the space!
my $validated_address = undef;
if($validated_address = Email::Valid->address($address)){
print "Valid!: $validated_address";
}
else {
print "NOPE!";
}
# prints, NOPE!
</code></pre>
<br />
This certainly makes things confusing. The reason that the email address gets modified, is that under the hood, <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> turns the address you give it, into a <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> object (it'll also just accept an <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> object, and <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> itself will take out that pesky space in the domain part of our email address, when it's own <span style="font-family: "Courier New",Courier,monospace;">address()</span> method returns a string:<br />
<br />
<pre><code>
#!/usr/bin/perl
use Mail::Address;
my $address = 'someone@example .com'; # notice the space!
my $modified = ( Mail::Address->parse($address) )[0]->address;
print $modified;
# prints, someone@example.com
</code>
</pre>
This makes it difficult to patch up <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span>, since then I'd have to delve into <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> - and perhaps <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> has a perfectly good reason to do this. Since both <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> and <span style="font-family: "Courier New",Courier,monospace;">Mail::Address</span> have been around for so long, and many programs have been written with their API the way it is, it's a pretty good bet they'll stay this way.<br />
<br />
So, what to do? Since my app's validation system is a little more than, "is the form correct?" it's difficult in the workflow to take in account of the changes <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> makes to the address I pass - I'm not sure if I even like the idea: getting a boolean back in a validation method seems a better idea - most of my own valiation methods in the app have the pattern of, return a boolean status, plus a hashref saying what may be wrong,<br />
<br />
<pre><code>
# In a perfect world:
my ($status, $errors) = $validater->check_out_this_address($address);
if($status == 1){
# Good to go!
}
else {
print "Dude, PROBLEMS:\n";
for (keys %$errors){
print '* ' . $_ . "\n";
}
}
</code></pre>
<br />
So, for example, say I'm importing a whole address book of addresses - thousands of addresses! And before I do that, I sort out the duplicate addresses, as the validation steps are many, and cpu consuming. Using <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> the correct way could introduce subtle bugs into the system. Simplifying things:<br />
<br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
# Say, I've already sorted out dupes:
my @check_these =
(
'one@foobar.com',
'another@foobar.com',
'another@foobar .com',
'two@foobar.com',
'blech'
);
my @validated = ();
my @invalid = ();
for(@check_these){
my $address;
if($address = Email::Valid->address($_)) {
push(@validated, $address);
}
else {
push(@invalid, $_);
}
}
print "Good! Addresses:\n";
print "* $_\n" for @validated;
print "BAD! Addresses:\n";
print "* $_\n" for @invalid;
</code></pre>
This prints out, <br />
<pre><code>
Good! Addresses:
* one@foobar.com
* another@foobar.com
* another@foobar.com
* two@foobar.com
BAD! Addresses:
* blech
</code></pre>
<br />
As you can see, some weird things happen:<br />
<ul>
<li>The number of addresses total that are returned isn't the same as what gets passed</li>
<li>All the invalid address are not reported</li>
<li>my once unique list now isn't so unique anymore. </li>
</ul>
<br />
I'm not sure yet what the best thing to do is. For now, sadly, I have to do something hacky in my own email (in form) validator - I just look for a space, if there's a space, it's automatically invalid:<br />
<br />
<br />
<pre><code>
#!/usr/bin/perl
use Email::Valid;
my $address = 'someone@example. com'; # notice the space!
if(is_valid_email($address)){
print "Valid!";
}
else {
print "Nope!";
}
sub is_valid_email {
my $a = shift;
if($a =~ m/\s/){
return 0;
}
if(Email::Valid->address($a)){
return 1;
}
else {
return 0;
}
}
# prints, Nope!
</code></pre>
<br />
So many miscalculations on my part, which! means much to learn from my own dumb self:<br />
<br />
Firstly, I couldn't believe it was a bug, since the way things have worked hadn't been changed in eons. <br />
<br />
Next: way back when I first wrote put this validation stuff in the app yarns ago, I was thinking that <span style="font-family: "Courier New",Courier,monospace;">Email::Valid</span> was nothing but a nice wrapper around a very, very complex regex created by <a href="http://regex.info/">Jeffrey Friedl</a> back in the day for a book on Regular Expressions that he wrote. <a href="https://gist.github.com/justingit/7012331/raw/184bd5fdcc0ab419c9cb6cdf9c59fb0c27e178ef/gistfile1.pl">It looks a little like this</a>. It's a doozy.<br />
<br />
Another miscalculation I had made was, <i>"I have tests! How could this fail!"</i> and I made the assumption the user was in fact on the wrong. So, I looked at my tests ,and whatayaknow: <br />
<pre><code>
TODO: {
local $TODO = 'This test fails.';
ok(valid_email_sub('test@example .com') == 0);
};
</code></pre>
<br />
So I actually knew about this problem before, and forgot - there's actually a link to a bug tracker in the actual test, which means I had handed off the problem to someone else to fix. <i>Lazy!</i><br />
<br />
<b>Things to learn: </b><br />
<i> </i><br />
<ul>
<li>Read the docs! This very peculiarity is documented in Email::Valid's own docs. Don't assume! </li>
</ul>
<code></code><br />
<pre><code>Let's see an example of how the address may be modified:
$addr = Email::Valid->address('Alfred Neuman <neuman foo.bar="">');
print "$addr\n"; # prints Neuman@foo.bar
</neuman></code></pre>
<br />
<ul>
<li>Just because you think everything's working, doesn't mean there aren't weird little edge cases - it's probably a given.</li>
<li>Tests are good! Skipping tests that don't pass doesn't always help you. </li>
<li>Reporting bugs in other modules is good! Trying to fix them? Probably better. </li>
</ul>
<br />
My thanks to <i>rjbs</i> for being patient as I stumble around a module he has been nice enough to adopt, warts and all. <br />
<i> </i>
Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-2118058455075556259.post-63612881795862629262013-10-01T22:34:00.002-07:002013-10-01T22:44:08.242-07:00Dada Mail v6.7.0 Released! Save as Draft, Enhanced Attachments, jQuery Plugin<b>Dada Mail, v6.7.0 has been released!</b> Hurrah! You can read the <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dada_announce/20131001183416/">official announcement here</a>, <a href="http://dadamailproject.com/support/documentation-6_7_0/changes_6_x.pod.html#features_6_7_0">view the changelog</a>, as well as <a href="http://dadamailproject.com/support/documentation-6_7_0/install_dada_mail.pod.html">download/install it yourself</a>. If you're looking for a simple to use mailing list manager (written in Perl), give it a go! It's one of the few Perl apps that's available as a one-click install in many services that you'll see in hosting control panels, like cPanel - safe to say, it's installed a ton!<br />
<br />
Feel free to explore away Dada Mail Lane - but that's not really what I wanted to focus on this blog post. What I really wanted to focus on, is how Perl and CPAN has helped me ship the new features of this app in a matter of weeks. So let's do it!<br />
<br />
<h2>
Feature! Save as Draft</h2>
<br />
<iframe allowfullscreen="" frameborder="0" height="480" src="//www.youtube.com/embed/W3QGexzMwug" width="640"></iframe>
The <b>Save as Draft</b> feature in Dada Mail allows you to start writing a message, then allow you to save it as you go, so you don't have to finish creating a message in one sitting. It's very similar to the auto-save feature in the blog software I'm using right now to author this post!<br />
<br />
When I create a new feature, there's a few things I like to make sure I'm doing right: I like to make things as simple as possible, but have room for future growth. I can't predict the future, but I still can try to think of features that I would like to work on, in the future.<br />
<br />
For Save as Draft, the backend is super simple: the SQL table (Dada Mail supports MySQL, PostgreSQL and SQLite) looks a little bit like this:<br />
<br />
<pre>
CREATE TABLE IF NOT EXISTS dada_message_drafts (
id INT4 NOT NULL PRIMARY KEY AUTO_INCREMENT,
list varchar(16),
created_timestamp TIMESTAMP DEFAULT NOW(),
last_modified_timestamp TIMESTAMP,
name varchar(80),
screen varchar(80),
role varchar(80),
draft mediumtext
);
</pre>
<br />
<b>id</b> is your primary key,<br />
<br />
<b>list</b> is used to distinguish what list the draft messages belong to.<br />
<br />
<b>created_timestamp</b> and <b>last_modified_timestamp</b> give some file status-type information on your draft, since you can think of a draft as a sort of document. It's nice for example, to be able to sort your drafts by their <b>last_modified_timestamp</b>, so we can always load up the most recent draft, when someone visits the screen that we use to edit a message.<br />
<br />
Speaking of the two timestamp cols in thw same table, there seems to be many different opinions on how exactly to use them together, as some databases don't allow you to have >1 cols with a default timestamp values. Again, for simplicity sake, I decided to make <span style="font-family: "Courier New",Courier,monospace;">INSERTS</span> set the created_timestamp automatically, and setting the last_modified_timestamp explicitly:<br />
<br />
<pre>INSERT INTO dada_message_drafts (list, screen, role, draft, last_modified_timestamp) </pre>
<pre>VALUES (?,?,?,?, NOW());
</pre>
<br />
and then <span style="font-family: "Courier New",Courier,monospace;">UPDATES</span> would again just explicitly update the last_modified_timestamp<br />
<br />
<code>
UPDATE dada_message_drafts SET screen = ?, role = ?, draft = ?, last_modified_timestamp = NOW() WHERE list = ? AND id = ?;
</code>
<br />
<br />
<b>Again:</b> simple, simple, simple.<br />
<br />
A bigger problem I faced was basically how to save what is going to be an ever-changing set of form fields. I didn't want the Save as Draft feature to dictate what I'd be presenting the user in terms of widgets and things that they can utilize. <i> </i><br />
<br />
<i>Maybe</i> one day, I want to set up how the Partial List Sending feature works differently in the next version, but not have to worry about having a column in this table for drafts now useless, or worse: shoehorned for a feature it wasn't meant to be -<br />
<br />
I didn't want this:<br />
<br />
<pre>
CREATE TABLE IF NOT EXISTS dada_message_drafts (
id INT4 NOT NULL PRIMARY KEY AUTO_INCREMENT,
list varchar(16),
created_timestamp TIMESTAMP DEFAULT NOW(),
last_modified_timestamp TIMESTAMP,
name varchar(80),
screen varchar(80),
role varchar(80),
header_subject,
custom_header_1,
message_plaintext,
message_html mediumtext,
attachment_1 mediumtext,
attachment_2 mediumtext,
attachment_3 mediumtext,
custom_widget_value_1 mediumtext
);
</pre>
<br />
Blech. Rather, it made more sense to encode all the form values together, and have an easy way to decode them, which runs right into the next problem:<br />
<br />
Now that I have the values to fill in my form - well, how do I do that, easily - and more importantly with the flexibility I want. It's a big-time drain problem - sure: filling out a text field is easy, but how about a check box array, or a popup form? <i>Forget it!</i><br />
<br />
So, of course there's a solution in Perl/CPAN! And the one I decided upon was <a href="https://metacpan.org/module/HTML::FillInForm::Lite">HTML::FIllinForm::Lite</a>. Lite, because this app is shipped with any required modules (the app is easy to install for people who know nothing of cpan/cpanm/perlbrew/so one and so forth) and that also means no XS modules, outside the core.<br />
<br />
HTML::FillinForm::Lite requires a datasource to use to fill in the HTML form fields (that you also supply) and one of the data sources it supports is an object with a param() method, like <a href="https://metacpan.org/module/CGI">CGI.pm</a> (yes! I still use CGI.pm - Dada Mail requires only Perl v5.8.1 and a CGI env. to work!) CGI.pm itself has a way to "<a href="https://metacpan.org/module/CGI#SAVING-THE-STATE-OF-THE-SCRIPT-TO-A-FILE">save the state of the form</a>", which sounds goofy, but is exactly what we need to do! The examples in its own docs only show how to write to a filehandle, and it's a little easier to passa scalar to a database handle, so you can do something like this very Perlish trick, to get the data into a string form: <br />
<br />
<pre>
sub stringify_cgi_params {
my $self = shift;
my ($args) = @_;
if ( !exists( $args->{-cgi_obj} ) ) {
croak "You MUST pass a, '-cgi_obj' parameter!";
}
my $q = $args->{-cgi_obj};
$q = $self->remove_unwanted_params(
{
-cgi_obj => $args->{-cgi_obj},
}
);
my $buffer = "";
open my $fh, ">", \$buffer or die 'blarg!' . $!;
$q->save($fh);
return $buffer;
}
</pre>
<br />
<br />
The old, "open filehandles directly to Perl scalars" trick (<code>open my $fh, ">", \$buffer or die 'blarg!' . $!;</code>)
<br />
<br />
Once we want to repopulate the form, it's easy enough to decode those form fields, again, like so:<br />
<br />
<br />
<pre>sub decode_draft {
my $self = shift;
my $saved = shift;
open my $fh, '<', \$saved || die $!;
require CGI;
my $q = CGI->new($fh);
return $q;
}
</pre>
<br />
<span style="font-family: "Courier New",Courier,monospace;">$q</span> is now a CGI object, that we can pass right to HTML::FillinForm::Lite:
<br />
<br />
<pre>require HTML::FillInForm::Lite;
my $h = HTML::FillInForm::Lite->new();
$str = $h->fill( \$html_str, $q );
</pre>
<br />
<br />
<br />
Couldn't be any simpler.<br />
<br />
<h2>
Features! Attachments</h2>
<iframe allowfullscreen="" frameborder="0" height="480" src="//www.youtube.com/embed/LjLJGRvOyUY" width="640"></iframe><br />
<br />
Dada Mail has supported sending a message out with attachments for quite some time - I can't remember I time it didn't, but it only presented the user with a file upload widget, for the user to pick a local file. Not very flexible, and not something that was going to work, as it's not really possible to save the state of the file upload widget without <i>really</i> jumping through some flaming hopes - so let's not. <br />
<br />
What I really needed was something a lot more flexible: I wanted to allow the user to pick a file from their local computer, as well as have available files that have already been uploaded. I also wanted it easy to add an attachment, but also remove one, if they decide against it. Finally, and most importantly, it had to all work with the new Drafts feature - so, if we're using a different form field - something HTML::FillinForm::Lite can fill in, that would be ideal.<br />
<br />
Dada Mail already ships with a a web file browser called, <a href="http://kcfinder.sunhater.com/">KCFinder</a>, which itself is an alternative to a somewhat expensive add-on to CKEditor called, <a href="http://cksource.com/ckfinder">CKFinder</a>. Luckily, KCFinder works flippin' <i>great</i> as a image uploader for Dada Mail's HTML message text box. Could I use it to simply fill in the value of a form field?<br />
<br />
I wasn't looking forward to reverse engineering how KCFinder talks to CKEditor, but to my surprise, there was an <a href="http://kcfinder.sunhater.com/demos/textbox">already-working example</a> on KCFinder's site, that shows you how to open a new KCFinder window, and then capture the name of the file selected, for you to do anything you want with - say fill in a text field. Perfect! With a few flurishes, that feature was stamped out, in record time.<br />
<br />
Incidentally, KCFinder has a semblance of security by using a sessioning system, so that only the right people can have access to its file upload/browsing feature. You don't want just anyone to be able to upload file type X to your server. <i>Nightmarish!</i><br />
<br />
Dastardly, KCFinder's server backend is in PHP, so it uses PHP-style-sessioning. Not the happiest place to be, if you have a Perl app. Thankfully, there's <a href="https://metacpan.org/module/PHP::Session">PHP::Session</a> to bridge the PHP-style, Perl-style gap. Saved again! <br />
<br />
<h2>
Feature! jQuery Plugin</h2>
<h2>
<iframe allowfullscreen="" frameborder="0" height="480" src="//www.youtube.com/embed/4strH1a2k3g" width="640"></iframe></h2>
<br />
<h2>
</h2>
Perhaps some will remember the Bad Old Days, when one's JavaScript was a mish-mash of ill-begotten weird lines of noise - back before their was a framework of any way/shape/form to 'rastle all this stuff together. Dada Mail harkens back to the winter of <i>1999</i>, and it's gone through many iterations of its JavaScript functionality - from minor flourishes, to utilizing <a href="http://prototypejs.org/">prototype.js</a> and <a href="http://script.aculo.us/">Scriptaculous</a>, and of course porting all that to <a href="http://jquery.com/">jQuery</a>.<br />
<br />
With learning jQuery, one wants to <a href="http://learn.jquery.com/plugins/">make a jQuery plugin</a>, and one learns sort of a dirty little secret: there's no one way to do so! <a href="http://learn.jquery.com/plugins/advanced-plugin-concepts/">It's filled with compromises</a> (I mean - check it! It even states: <i>Remember, it's a compromise</i>!), and metric ton of boilerplate code. You can't really think of a plugin as having a namespace, as plugins kinda only support one, "method". It makes Perl's OO system look exceptionally attractive. What a train wreck. Sigh. <br />
<br />
So, I guess(?) you just sort of have to except that this a very warty part of jQuery, and JavaScript is sort of a very warty thing in of itself, but there's no alternative. My only real constraint that I wanted was to have > 1 method available. For this plugin: I wanted to be able to create a subscription form, that ties into a Dada Mail, mailing list, and I also wanted a method to control an already existed form, so that a designer can have full control on the presentation of the form, if they don't like what gets created by the plugin itself.<br />
<br />
<a href="https://gist.github.com/Club15CC/1300890">I used this boilerplate</a> as a basis for my own plugin (<i>179 lines!</i> Of <i>boilerplate!</i>). and created the two, "methods" I wanted, and once you get your brain around how things work, it was, eh, OK. Once the plugin takes control of a form, either one it creates, or one it, "takes control of", I wanted to simply show the results of a subscription request, in a modal window. Like-a-dis:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0X-dTSR4S25QF2h8gQKqOD45tS1GSbvgUyZ2eStruSmUjeor2G_lt8hURG7JxSHI4d7pAzg57KyysN6lv99irAbilT7LE3INVrJc1RDpgjHurb-j6EeerBfybQC91UAFKymZERn0RHuY/s1600/confirm_message_example.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0X-dTSR4S25QF2h8gQKqOD45tS1GSbvgUyZ2eStruSmUjeor2G_lt8hURG7JxSHI4d7pAzg57KyysN6lv99irAbilT7LE3INVrJc1RDpgjHurb-j6EeerBfybQC91UAFKymZERn0RHuY/s400/confirm_message_example.jpg" width="400" /></a></div>
<span id="goog_1546875431"></span><span id="goog_1546875432"></span><br />
<br />
Luckily, Dada Mail already takes advantage of another jQuery plugin, called <a href="http://www.jacklmoore.com/colorbox/">Colorbox</a>, so it was easy enough to leverage that for our modal window. The trick really was having jQuery talk to Dada Mail, and for that we use Dada Mail's sparkling new RESTful interface, that jQuery can talk to via JSONP, which itself is a weird hackity hack, to get over a security thing-a-mabob. Great!<br />
<br />
Like a ton of things in Perl, working with JSON is pretty darn easy. Here's how we take a request from jQuery:<br />
<br />
<pre>$.ajax({
url: $("#" + targetForm).attr("action") + '/json/subscribe',
type: "POST",
dataType: "jsonp",
cache: false,
data: JSON.stringify(
{
list: $("#" + targetForm + " :input[name='list']").val(),
email: $("#" + targetForm + " :input[name='email']").val(),
fields: fields
}
),
contentType: "application/json; charset=UTF-8",
success: function(data) {
/* Do something, after success! */
$.colorbox({
html: '<h1>
Hey, that worked!</h1>
',
opacity: 0.50
});
},
error: function(xhr, ajaxOptions, thrownError) {
console.log('status: ' + xhr.status);
console.log('thrownError:' + thrownError);
$.colorbox({
html: '<h1>Apologies,</h1>An error occured while processing your request. Please try again in a few minutes.',
opacity: 0.50
});
}
});
</pre>
<br />
<br />
And here's how we could handle the request:
<br />
<br />
<pre> require JSON::PP;
my $json = JSON::PP->new->allow_nonref;
if ( !$q->content_type || $q->content_type =~ m/text\/html/ ) {
# Perhaps, die here? Show the API docs?
}
elsif ( $q->content_type =~ m/application\/json/ ) {
# well. OK, then.
}
else {
die '425';
}
my $post_data = $q->param('POSTDATA');
my $data = undef;
try {
$data = $json->decode($post_data);
}
catch {
die '400';
};
# Now, we can work with $data!
</pre>
<br />
<br />
the <span style="font-family: "Courier New",Courier,monospace;">$data</span> hashref now contains the parameters that the jQuery stuff passes to us (list to subscribe to, email to subscribe with, etc). I did a ton of housekeeping in Dada Mail's own system to make it dead easy to go through the subscription process, and have the method return a quite the complex data structure - with which you can gleam all sorts of information from: was it successful? No? What was the problem? What should I do now - show a message? redirect to a different URL?<br />
<br />
A complex data structure is fine, but it's a Perl complex data structure. Thankfully, turning a data structure into JSON for jQuery to understand is again, dead simple:<br />
<br />
<br />
<pre> my $fancy_data = {
email => 'you@yours.com',
list => 'somelist',
status => 1,
fancy_message => 'Hey, that worked! Hurrah!',
};
require JSON::PP;
my $json = JSON::PP->new->allow_nonref;
my $data_back = $json->pretty->encode($fancy_data);
</pre>
<br />
<code>$data_back</code> will now be the following JSON:
<br />
<pre>
{
"email" : "you@yours.com",
"status" : 1,
"fancy_message" : "Hey, that worked! Hurrah!",
"list" : "somelist"
}
</pre>
<br />
I'm actually really glad I had to figure out how to make things work by creating this JSON response, as it truly forced me to make the Perl code clear, pragmatic, and a whole less complex - which surprisingly made things a lot more flexible. Kind of like being in the middle of a solitaire game you know you're going to win, there's more simplification I can do to really drill down and make things way easier to read. Again: no real tricks, just elbow grease and going in there and making small changes, which add up!<br />
<br />
<a href="http://dadamailproject.com/support/documentation-6_7_0/COOKBOOK-subscriptions.pod.html#restful_api">Here's the docs to the jQuery plugin, as well as the RESTful interface</a> (which is still very much in a moving-and-shaking phase of things - I still have a ton to learn!), that'll give you a better idea on how this all fits together - it's complete with full examples of using the interface in both a Perl app, as well as your own jQuery app. The jQuery plugin for this release <a href="https://github.com/justingit/dada-mail/blob/v6_7_0-stable_2013_10_01/dada/static/javascripts/jquery.dadamail.js">can be viewed here</a>.<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-23286536860016423602013-09-06T11:48:00.002-07:002013-09-06T11:48:54.939-07:00Dada Mail, v6.6.0 Released!I've just put out a new release of <b><a href="http://dadamailproject.com/">Dada Mail</a> - v6.6.0</b>. Its a web-based mailing list manager, written in Perl. You can check out/fork/push/pull the source code <a href="https://github.com/justingit/dada-mail">here</a>. Some of its main goals is to be pretty easy to install by mere mortals, easy to work with, yet pretty darn powerful and flexible, to fill a ton of different needs - it's not really trying to be a replacement to the creaky Majordomo, or Mailman. <br />
<br />
I'm heading up to my <i>14th year</i> of developing the application. It's currently free to download from <a href="http://dadamailproject.com/download">its own support site</a> as well as from various installer services that have popped up in the last few years (<a href="http://www.mojomarketplace.com/scripts/ajax_details/166fb0cc-0c17-11e2-8b3b-0030483370c8">Mojo Marketplace</a>, <a href="http://installatron.com/dadamail">Installatron</a>, <a href="http://demo.softaculous.com/enduser/index.php?act=perl&soft=440">Softaculous</a>, etc) Follow along with the project on <a href="https://twitter.com/dadamail">Twitter</a>, or hey - we have a <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dada_announce/">mailing list too</a>! <br />
<br />
There's lots of things a like about working on it, but the application has become quite monolithic, and a little less flexible in its underlying code, than I'd like. In the next few months, I'm hoping to alleviate that, without falling into the problem of <a href="http://www.joelonsoftware.com/articles/fog0000000069.html">totally rewriting the app</a> (it would be almost impossible to do so, with a one-dude team).<br />
<br />
My initial idea is to move from basically <i>no</i> framework, to working with <a href="https://metacpan.org/module/CGI::Application">CGI::Application</a>. That should help me gain some sort of framework, and a way to break the overgrowth of parts of this app, into more manageable pieces. It'll also hopefully give me a bridge to be able to have Dada Mail run as a CGI script (how people are used to running Dada Mail), as well as a PSGI app (a great alternative, that has a TON of benefits, one being SPEED!).<br />
<br />
From there, we'll see how it works, but it may be time to move on to some more whiz-bang things that a framework like <a href="https://metacpan.org/module/Mojolicious">Mojolicious</a> would provide. The bummer with trying to move to Mojolicious is that the Perl version required is rarely met on the shared hosting accounts that the majority of people who run Dada Mail are on. Saying, "hey, just install perlbrew!" is a far cry on what lots of people are capable of. They're used to a one-click install. Sigh.<br />
<br />
Maybe cPanel, being a Perl-based shop, knows of a better way to have available a more up-to-date Perl version? A how-to, so not to fudge this up, would be super-helpful and somewhat break huge shackles from those that ship apps for this types of hosting situations. (maybe you know?)<br />
<br />
Without further ado, here's the changelog from this last release:<br />
<br />
<br />
<a name='more'></a><br />
<h2>
<a href="http://www.blogger.com/null" name="summary_6_6_0">Summary 6.6.0</a></h2>
This release of Dada Mail focuses on three main features:<br />
<ul>
<li><strong><a class="item" href="http://www.blogger.com/null" name="sending_error_detection_and_reporting">Sending Error Detection and Reporting</a></strong>
</li>
<li><strong><a class="item" href="http://www.blogger.com/null" name="redesigned_membership_admin_screen">Redesigned Membership Admin Screen</a></strong>
</li>
<li><strong><a class="item" href="http://www.blogger.com/null" name="new_restful_api_for_subscriptions">New RESTful API for Subscriptions</a></strong>
</li>
</ul>
<h2>
<a href="http://www.blogger.com/null" name="features">Features</a></h2>
<h3>
<a href="http://www.blogger.com/null" name="mass_mailing_enhancements__sending_error_detection_and_reporting">Mass Mailing Enhancements: Sending Error Detection and Reporting</a></h3>
Dada Mail has enhanced its sending error detection during mass
mailings. Due to how many messages go out during a mass mailing and how
fast you may be sending out these messages, problems with mail sending
could potentially happen. Historically, Dada Mail has been less than
bright than it could be when handling and reporting these problems.<br />
Dada Mail is now tuned to catch addresses causing problems and perform some intelligent tasks:<br />
<h4>
<a href="http://www.blogger.com/null" name="problems__try_again_">Problems?! Try again.</a></h4>
If a message to an address is not sending out correctly, Dada Mail
will now wait a small period of time (a few seconds), and try sending
twice more. This should help with any <em>very</em> temporary problems
dealing with your mail system itself (your own MTA, an outside SMTP
server, or service like Amazon SES). Hey, things happen, every once in
awhile. The idea is that brief hiccups on your end, shouldn't mean a
subscriber misses receiving an important message from you.<br />
<h4>
<a href="http://www.blogger.com/null" name="still_having_problems_give_it_a_rest_and_try_again__one_more_time">Still having problems? Give it a rest and try again, one more time</a></h4>
If, after three tries sending the message, the message still doesn't
get sent, Dada Mail will now temporarily stop it's entire mass mailing
process and start again, after a slightly longer amount of time (a few
minutes). This is to make sure there isn't a problem with Dada Mail
itself - the resources its taking on the server, or any other very
strange, very fringe problems.<br />
After this wait, Dada Mail will start its mass mailing process at the
address that was having the delivery problems and try for another round
of three more times - just to make sure. If this is successful, great!
Business as usual. If the address fails in sending, the address is
logged, and skipped over and the next address is then sent to.<br />
<h4>
<a href="http://www.blogger.com/null" name="sending_error_log_and_report_">Sending Error? Log and Report.</a></h4>
This is a marked improvement over what Dada Mail has done in the
past: basically do nothing very intelligent when an address fails during
sending. Addresses that fail are now reported, using the Tracker
plugin, which allows you to see exactly which addresses are causing
problems (this data can be exported as a .csv file, as well!) and what
percentage of your total mailing list is having problems with sending
errors.<br />
Now that you know this information, you can then take some action to
fix it. The majority of problems on cheap, shared hosting platforms are
related to mass mailing <em>speed</em>: you're sending too fast.<br />
This is also the eaisest types of problem sto fix, as Dada Mail
supports changing how fast a mass mailing goes out, through it's batch
sending system. For more complicated problems, you can then look in Dada
Mail's error logs for more details - Dada Mail's Log Viewer plugin also
makes this easy.<br />
<h4>
<a href="http://www.blogger.com/null" name="track_it_">Track it.</a></h4>
Since sending errors are now reported, the reports created by the
Tracker plugin can now be more accurate. Message opens, bounce rates,
etc. percentages now do not count addresses that failed to even be sent
out by Dada Mail, giving you a better idea on how many messages were
interacted with, compared to how many were sent out, correctly (rather
than the full total).<br />
<h4>
<a href="http://www.blogger.com/null" name="feedback_welcome_">Feedback Welcome!</a></h4>
We're sure we'll be getting a lot of feedback from users that are
just noticing that they may be having problems on their end with
sending. We're hoping that armed with this new data, that deliverability
will increase.<br />
<h3>
<a href="http://www.blogger.com/null" name="tracker_plugin_enhancements__sending_errors">Tracker plugin enhancements: Sending Errors</a></h3>
Along with logged Sending Errors, the Tracker plugin has been updated to report those errors in a easy-to-digest way:<br />
<h4>
<a href="http://www.blogger.com/null" name="the_basics_pie_chart">"The Basics" Pie Chart</a></h4>
Sending Errors are first shown reported, per message, in the first
Pie Chart at the top of the screen. The pie chart is composed of
Delivered Messages, Hand/Soft Bounces, as well as addresses that had
Sending Errors.<br />
Sending Errors are also reported in the right-hand table, under, <strong>Sending Errors</strong> as both the total number of Sending Errors, and the percentage compared to how many addresses were sent to.<br />
<h4>
<a href="http://www.blogger.com/null" name="sending_errors_tab">"Sending Errors" tab</a></h4>
<strong>Sending Errors</strong> also has its own tab, underneith, <strong>The Basics</strong>.
This tab will both list the addresses where Sending Errors happened, as
well as a pie chart, broken down by domain. There's also an option to
export these addresses as a .csv file.<br />
<h4>
<a href="http://www.blogger.com/null" name="other_tracker_changes__more_accurate_report_percentages">Other Tracker changes: more accurate report percentages</a></h4>
The Tracker plugin now shows percentages to the nearest tenth of a
percent, rather than rounding up numbers to the nearest whole number.
This helps in getting a better picture of what's happening with your
mailing list: things like Sender Errors, Bounces and Unsubscribes could
be a very small amount of activity, when compared to how large your
mailing list is.<br />
<h3>
<a href="http://www.blogger.com/null" name="working_with_subscribers__more_powerful_tools">Working with Subscribers: More Powerful Tools</a></h3>
List Owners now have much more powerful tools to work with individual
subscribers of their mailing lists, as well as the ability to work
across different mailing lists. The completely rewritten Membership
screen now has four separate tabs to work with your mailing list member:
<strong>Membership</strong>, <strong>Subscriber History</strong>, <strong>Mailing List Activity</strong>, <strong>Profile</strong>.<br />
<h4>
<a href="http://www.blogger.com/null" name="membership">Membership</a></h4>
The Membership tab allows you to work with the email address of one of your mailing list members. Here, you may <strong>Add</strong>, <strong>Update</strong> or <strong>Remove</strong> the address for your mailing list. A Dada Mail mailing list is actually composed of many different <strong>sublist</strong> types. So, for example, when you send a mass mailing out, you're sending a message out to your <strong>Subscribers</strong> sublist.<br />
But, Dada Mail has other sublists that provide different roles. For example, Dada Mail's <strong>Black List</strong> allows you to have a list of addresses that aren't allowed to join your list. This is also known as a, <strong>Suppression List</strong><br />
The, <strong>Authorized Senders</strong> sublist is a list of
addresses that are allowed to send out a message from their own mail
reader, without having to log into Dada Mail, that then gets delivered
to your Subscribers (this is done with the Bridge plugin, which is
bundled with Dada Mail)<br />
The Membership tab allows you to Add/Update/Remove addresses across
these sublists. If you're logged into a mailing list with the Dada Mail
Root Password, you'll also be able to do all things things, across all
your mailing lists.<br />
Dada Mail is smart when allowing you to work with the addresses that
make up your mailing list, as these addresses are the most valuable
asset of the whole system. Checks are done to make sure you're not going
to mess up subscriptions, and all these functions only happen after
Dada Mail validates your request and <em>you</em> confirm the changes.<br />
Listed in the <strong>Membership</strong> tab will be all the <strong>sublists</strong>
an individual email address is a member of, for the Mailing List you're
currently logged into. Be aware that one address may be a member of <em>multiple</em> sublists.<br />
For example, an address may be both a <strong>Subscriber</strong> (Subscribers receive mass mailings sent to the mailing list), an <strong>Authorized Sender</strong>
(Authorized Senders are able to send messages via Bridge, as well as
moderate messages sent via Bridge to a mailing list set up as a
discussion list), as well as being on the <strong>White List</strong> (Only White Listed members are allowed to subscribe to a mailing list).<br />
An address could also be simply on the <strong>Black List</strong>, with no permission to be a member of your <strong>Subscribers</strong>, until they're first removed from the Black List and added to the <strong>Subscribers</strong> sublist.<br />
If an address is currently on the <strong>Subscription Requests</strong> sublist, they will be awaiting approval from the List Owner to join the Subscribers sublist. You may <strong>Approve</strong> or <strong>Deny</strong> this request on this screen as well.<br />
<h4>
<a href="http://www.blogger.com/null" name="subscriber_history">Subscriber History</a></h4>
Dada Mail logs the subscriber history of an address: when the address
was added/updated/removed from one of your mailing lists and their
underlying sublists. This, "paper trail" helps out when painting a
picture of how this address has become a part of your mailing list.
Information recorded includes the time of the add/update/removal, IP
address of the request, and what exactly was done with the address.<br />
This information can also be exported in a .csv format, to be opened
and worked with, in any application that understand this format - things
like Excel or other spreadsheet applications.<br />
If you have logged into your mailing list with the Dada Mail Root
Password, you may view the history for the mailing list you're currently
logged into, as well as all mailing lists - the latter can also be
exported to .csv format.<br />
<h4>
<a href="http://www.blogger.com/null" name="mailing_list_activity">Mailing List Activity</a></h4>
The, <strong>Mailing List Activity</strong> tab shows you how the
subscriber has interacted with the mass mailings you've sent. Things
like, Opens, Clickthroughs, Unsubscriptions, Sending errors, Hard/Soft
Bounces are tracked for each message you send out. This information is
shown for each recent mass mailing that's sent.<br />
Like the <strong>Subscriber History</strong>, this data can also be
exported in .csv format, to be opened up in an outside application. Data
that's exported includes the data and time of the activity, what type
of activity this was, if it was a clickthrough, what URL was clicked
through, the message id of the message, as well as the IP address the
subscriber was coming from.<br />
<h4>
<a href="http://www.blogger.com/null" name="profile">Profile</a></h4>
The Profile tab allows you to work with the Subscriber's Profile.
Dada Mail's Profile system allows you to save additional information,
other than an email address, that's association with your subscriber.
These fields are pretty free-form, so you can add whatever you'd like:
First Name, Last Name, City, State, Favorite Color, etc.<br />
These fields can be edited by the user themselves, as well as in this
tab. You may also change the password used by your user to access their
own information.<br />
<h3>
<a href="http://www.blogger.com/null" name="restful_subscription_interface_experimental">RESTful Subscription Interface EXPERIMENTAL</a></h3>
Dada Mail has a new <strong>EXPERIMENTAL</strong> RESTful interface
to its mailing list subscription system, which should allow you to use
it as a service in another app of yours. For more information, see the
Subscription Cookbook docs:<br />
<a href="http://dadamailproject.com/d/COOKBOOK-subscriptions.pod.html">http://dadamailproject.com/d/COOKBOOK-subscriptions.pod.html</a><br />
Examples of how to use this API are included, written in JavaScript
and Perl. A fully-functioning demo, complete with all the trimmings is
also included in this release, that you may use to explore the service.<br />
Earlier REST and SOAP experimental client/server scripts, located in the <em>dada/extras/scripts/subscribe</em> have now been removed. For this new RESTful interface, no additional scripts are needed to be installed.<br />
<h3>
<a href="http://www.blogger.com/null" name="administration_screen_changes">Administration Screen changes</a></h3>
Changes have been made to the, <strong>Administration</strong> screen
- if you are already logged into a mailing list, you'll be redirected
to the default list control panel screen (usually, <strong>Send a Message</strong>), rather than to the Administration screen, that simply <em>tells</em> you you're logged in and provides a link to go this same screen.<br />
<h3>
<a href="http://www.blogger.com/null" name="black_white_list_definition_changes">Black/White List Definition Changes</a></h3>
The Black List can currently hold email addresses,<br />
<pre> user@example.com</pre>
or parts of email addresses, like this:<br />
<pre> user@</pre>
<pre> @example.com</pre>
It wasn't entirely clear what was meant by, "part" of an address, so this has been clarified:<br />
The part of an email address <strong>must</strong> include the, <strong>@</strong>
symbol, to remove the ambiguity of if you want to Black List the user
or domain part of the address and something like this doesn't happen:<br />
<pre> example.com@someotherdomain.com</pre>
So the following are now <em>not</em> valid Black List (or White List) entries:<br />
<pre> user</pre>
<pre> example.com</pre>
If you do have entries like this in your current Black List/White List, they simply won't do much of anything.<br />
<h3>
<a href="http://www.blogger.com/null" name="installer">Installer</a></h3>
<h4>
<a href="http://www.blogger.com/null" name="enable_debugging_options">Enable Debugging Options</a></h4>
The included Dada Mail Installer now allows you to enabled Debugging
Options for Dada Mail. These debugging options add extra log information
in Dada Mail's own error log, and includes both modules that make up
Dada Mail, as well as bundled CPAN Perl modules. This option is located
under the, <strong>Advanced Configuration (Optional)</strong> heading, and is available in our Pro Dada distribution.<br />
<h4>
<a href="http://www.blogger.com/null" name="json_module_installed_if_needed">JSON module installed if needed</a></h4>
The JSON CPAN modules are used heavily in Dada Mail, but is not
installed by default on many hosting platforms. To make things easier,
the Dada Mail Installer will look to see if they're already installed
system-wide and if they're not, it will move a bundled Pure-Perl version
of the modules into its own perllib, thus making it available to be
used. This saves some time from having to manually doing this same thing
yourself, every time an upgrade is done.<br />
It's still suggested to install the JSON Perl module yourself to get
the XS-version for speed, either manually, or using cpan/cpanmin<br />
<h2>
<a href="http://www.blogger.com/null" name="changes_6_6_0">Changes 6.6.0</a></h2>
<h3>
<a href="http://www.blogger.com/null" name="the_dada_mail_manual">The Dada Mail Manual</a></h3>
The Dada Mail Manual has been updated to reflect the major overhaul fo the <strong>Membership</strong> list control panel screen.<br />
The, <strong>Using Tracker</strong> chapter has also been updated to reflect the new features in this released (logging and reporting Sending Errors)<br />
The, <strong>Mailing Sending - Options</strong> screen has also been updated to reflect the current options available.<br />
<h3>
<a href="http://www.blogger.com/null" name="profile_fields">Profile Fields</a></h3>
In previous versions of Dada Mail, the app had a curious, if not downright broken behavior when it come to Profile Fields:<br />
If a subscriber was a member of one mailing list, and was then
subscribed to another mailing list, any saved Profile Fields tied to
that address would be <strong>lost</strong> - even if that new subscription didn't have any new Profile Fields passed to Dada Mail.<br />
This behavior has now changed:<br />
If an address, that has saved Profile Field information, and is
subscribed to a mailing list, that original information will now be <strong>preserved</strong>. If an address is subscribed, but had no profile field information saved, any new information would then be <strong>saved</strong>.<br />
It's unclear yet what to do with a subscriber, that has saved Profile
Field information that's subscribed to another mailing list, along with
<em>new</em> Profile Field information - should the new information be
used instead? Should the old information be kept? Shoudl some sort of
sophisticated folding of data happen? Should it be a pref. somewhere?
(per mass import, in the list control panel?)<br />
We're not sure yet, but we encourage feedback.<br />
<h3>
<a href="http://www.blogger.com/null" name="uncompress_dada_cgi_script">uncompress_dada.cgi script</a></h3>
The helper script named, <code>uncompress_dada.cgi</code> is kept
intentionally simple, so as to be super-quick to download, and easy to
read along, if little niggling changes need to be made for your
environment. We've changed a few things to make things more flexible:<br />
Some people moving from Basic Dada Mail, to Pro Dada mail noticed that if BOTH the <code>dada-6_x_y.tar.gz</code> distro and <code>pro_dada-6_x_y</code> distro are present in your installing directory, the <code>dada-6_x_y.tar.gz</code> will be used, causing confusion. <code>uncompress_dada.cgi</code> will now explicitly look for the <code>pro_dada-6_x_y</code> first.<br />
<h2>
<a href="http://www.blogger.com/null" name="bugfixes_6_6_0">Bugfixes 6.6.0</a></h2>
<h3>
<a href="http://www.blogger.com/null" name="your_request_for_subscription_is_complete_html_screen_completely_missing">"Your Request For Subscription is Complete" HTML screen completely missing</a></h3>
<a href="https://github.com/justingit/dada-mail/issues/398">https://github.com/justingit/dada-mail/issues/398</a><br />
<h3>
<a href="http://www.blogger.com/null" name="welcome_message_to_addresses_subscribed_in_the_list_control_panel_does_not_provide_unsub_link__warning_in_the_list_control_panel">""Welcome"
Message to Addresses Subscribed in the List Control Panel" does not
provide unsub link, warning in the list control panel</a></h3>
<a href="https://github.com/justingit/dada-mail/issues/395">https://github.com/justingit/dada-mail/issues/395</a><br />
<h3>
<a href="http://www.blogger.com/null" name="mass_mailings_sometime_reload__without_end___browser_says__reloading_mailing___">Mass Mailings sometime Reload, without end - browser says, "Reloading Mailing..."</a></h3>
<a href="https://github.com/justingit/dada-mail/issues/399">https://github.com/justingit/dada-mail/issues/399</a><br />
<br />
<br />
<br />Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-2118058455075556259.post-2771058248756823352012-11-09T16:59:00.002-08:002012-11-09T16:59:58.751-08:00Dada Mail v6.0.0 Alpha 1 ReleasedThis is the 6th MAJOR release of this app I've made since December of 1999. I think that's pretty wild. <a href="https://github.com/justingit/dada-mail/compare/master...6_0_0-dev">Github</a> tells me that, compared to the last stable version of Dada Mail (v5.2.1) there has been: <b>353 changed files</b>
with <b>18,740 additions</b>
and <b>16,697 deletions. </b>Goodness.<br />
<b><br /></b>
One of the major focuses on this release has really nothing to do with Perl, but JavaScript - I managed, somehow to port all the Prototype/Scriptaculous code to jQuery. Sadly, the Prototype project seems to be dead. But gladly, the jQuery code that's now part of the app is <a href="https://github.com/justingit/dada-mail/blob/6_0_0-dev/dada/static/javascripts/dada_mail.js">pretty easy to read</a>.<br />
<br />
To those interested, here's a rundown of the differences between the v5 and v6, as well as the direct link to install,<br />
<br />
<ul>
<li><a href="http://dadamailproject.com/support/documentation-6_0_0/install_dada_mail.pod.html"><b>Install Directions</b></a> </li>
</ul>
<br />
<!-- INDEX BEGIN -->
<div name="index">
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="__index__"></a><br />
<hr name="index" />
</div>
<!-- INDEX END -->
<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="dada_mail_5_to_dada_mail_6_upgrade_guide">Dada Mail 5 to Dada Mail 6 Upgrade Guide</a></h1>
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="focus">Focus</a></h1>
The focus of this major release of Dada Mail is to make room for growth of the app, by creating a better foundation for future features.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="javascript_ui_ux_breathing_growing_room">JavaScript UI/UX Breathing/Growing Room</a></h2>
Dada Mail's UI/UX has been migrated to jQuery, from Prototype, where development has all but ceased.<br />
The vast majority of Dada Mail's extra functionality through JavaScript is done in an unobtrusive way. A great example of new features allowed with this JS library move is the rewritten and redesigned Tracker plugin.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="towards_a_new_web_framework">Towards a new web framework</a></h2>
Dada Mail is written with the thinnest of veneer of a web framework, and the next major version of Dada Mail may be a migration to a more robust web framework such as CGI::Application, Catalyst, or Mojolicious. v6 of Dada Mail moves the various components that make up Dada Mail (Perl code, JavaScript code, templates, images, stylesheets) into consolidated bundles of files and directories that are more sensible than previous versions.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="database_schema">Database Schema</a></h1>
There are <b>no</b> changes in any of the database schemas between Dada Mail 5 and Dada Mail 6.<br />
Upgrading is fairly straightforward, with no need for any Dada Mail 5 to Dada Mail 6 SQL upgrade scripts.<br />
When using the Dada Mail Installer (which you should use, when installing or upgrading), you will definitely want to create a new <code>.dada_config</code> file, when asked.<br />
There is one new config variable, <code>$SUPPORT_FILES</code> that needs to be set up correctly. If you do not make a new <code>.dada_config</code> file, or install manually, without putting in this new variable, the upgrade will not work.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="perl_version_requirements">Perl Version Requirements</a></h1>
This is currently <b>no</b> change in the Perl Version requirement of v5.8.1. This may change, before a stable release of v6 is released, most likely to v5.10.x of Perl. We're still working on that.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="_dada_config_file">.dada_config file</a></h1>
The <code>.dada_config</code> file that's generated by the included installer has undergone a few changes.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="removed_variables___files___templates___tmp___backups___archives___logs">Removed variables: $FILES, $TEMPLATES, $TMP, $BACKUPS, $ARCHIVES, $LOGS</a></h2>
These variables were added to the <code>.dada_config</code> file, but are almost kept the same as the default, ala:<br />
<pre> $FILES = $DIR . '/.lists';
$TEMPLATES = $DIR . '/.templates';
$TMP = $DIR . '/.tmp';
$BACKUPS = $DIR . '/.backups';
$ARCHIVES = $DIR . '/.archives';
$LOGS = $DIR . '/.logs';</pre>
Instead of taking up extra space and line noise, these files are simply added to the <code>dada/DADA/Config.pm</code> file as the default. You may still add these variables in the <code>.dada_config</code> file to change their default, but it's not really recommended. The, <code>$DIR</code> variable has been added to the <code>dada/DADA/Config.pm</code> as a true config variable, so you do not want to have the first line read,<br />
<pre> my $DIR = '/home/account/.dada_files';</pre>
Simply,<br />
<pre> $DIR = '/home/account/.dada_files';</pre>
Will be fine. Keeping, <code>my</code> will probably break things.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="added_variable___backend_db_type__removed_variables___subscriber_db_type___archive_db_type___settings_db_type___session_db_type___bounce_scorecard_db_type___clickthrough_db_type">Added variable: $BACKEND_DB_TYPE; Removed variables: $SUBSCRIBER_DB_TYPE, $ARCHIVE_DB_TYPE, $SETTINGS_DB_TYPE, $SESSION_DB_TYPE, $BOUNCE_SCORECARD_DB_TYPE, $CLICKTHROUGH_DB_TYPE</a></h2>
For the SQL backend, all these variables are already set the same, ala:<br />
<pre> $SUBSCRIBER_DB_TYPE = 'SQL';
$ARCHIVE_DB_TYPE = 'SQL';
$SETTINGS_DB_TYPE = 'SQL';
$SESSION_DB_TYPE = 'SQL';
$BOUNCE_SCORECARD_DB_TYPE = 'SQL';
$CLICKTHROUGH_DB_TYPE = 'SQL';</pre>
For the Default backend, they're set like this:<br />
<pre> $SUBSCRIBER_DB_TYPE = 'PlainText';
$ARCHIVE_DB_TYPE = 'Db';
$SETTINGS_DB_TYPE = 'Db';
$SESSION_DB_TYPE = 'Db';
$BOUNCE_SCORECARD_DB_TYPE = 'Db';
$CLICKTHROUGH_DB_TYPE = 'Db';</pre>
To reduce line noise, <code>$BACKEND_DB_TYPE</code> is being introduced. If set to, <code>SQL</code>,
it'll set the other variables accordingly. Same with setting this variable to, <code>Default</code>.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="_sql_params__removed_table_names">%SQL_PARAMS: removed table names</a></h2>
Remove to further lesson the line noise.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="installer">Installer</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="database_connection__bounce_handler_pop3_connection_testers">Database Connection, Bounce Handler POP3 Connection Testers</a></h2>
The installer now has inline testers for both your Database Connection, and the Bounce Handler's POP3 Connection, to help you
make sure these work, before committing to an installation.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="installer_can_now_grab_information_from_the_previous_installation">Installer can now grab information from the previous installation</a></h2>
When using the installer to upgrade a current Dada Mail, it'll able to grab some of the configuration information from your previous installation: Program URL, Support Files Directory, Dada Mail Root Password, Backend Options, Plugin/Extensions that were previously installed, and your WYSIWYG options.<br />
<i>(If you added additional configuration variables after an install has completed, you will still have to re-add these manually)</i><br />
This can help save time during an upgrade and ensure that everything goes smoothly. You can also re-enable the installer, after a successful initial installation, to <i>change</i> your Dada Mail configuration - for example: add/remove a plugin.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="template_changes">Template Changes</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="templates_directory_move">"templates" directory move</a></h2>
In v5, template files lived in the directory:<br />
<i>dada/DADA/Template/templates</i><br />
They are now located in:<br />
<i>dada/templates</i><br />
It's hoped that this directory move will make it easier for people to find the <code>templates</code> directory. This directory is still in the, <code>dada</code> directory, instead of, say, the, <code>static</code> directory since template files are themselves little, simply programs, that need to be interpreted, and aren't themselves actually static.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="plugins__templated_out">Plugins: Templated out</a></h2>
There was a voluminous amount of inline HTML in the plugins/extensions that are shipped with Dada Mail. This HTML is now saved in separate template files, which you can find in,<br />
<i>dada/templates/plugins</i><br />
Each plugin has its own directory for its templates, eg: <i>dada/templates/plugins/tracker</i>, etc.<br />
The Scheduled Mailings plugin still has program generated and inline HTML. It's a big mess.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="javascript__images_and_css_files_removed_from_templates_directory__relocated_in__static_directory">JavaScript, images and css files removed from templates directory, relocated in, "static" directory</a></h2>
Many static files that used to reside in the, <i>templates</i> directory have been moved to the, <i>static</i> directory, to be
served directly from the webserver. These include JavaScript, image and cascading stylesheet files.<br />
This change should help performance of the app. These files are also not cached in Dada Mail's Screen Cache, as they're going to be served faster by
the webserver simply as static files.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="inline_javascript_removed_from_template_files">Inline JavaScript removed from template files</a></h3>
The vast majority of JavaScript that may have been found inline in the template files has been removed. You will now find that
code in the, <i>static/javascripts/dada_mail.js</i> file.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="javascript">JavaScript</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="migration_from_prototype_scriptaculous_to_jquery_jqueryui">Migration from Prototype/Scriptaculous to jQuery/jQueryUI</a></h2>
Most of the JavaScript that relies on the Prototype/Scriptaculous libraries has been migrated to jQuery/jQueryUI. Some remains,
and jQuery has been configured in, <code>NoConflict</code> mode. We hope to move all Prototype/Scriptaculous code to jQuery eventually.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="static_files_directory_location___support_files_config_variable__installation_and_configuration">Static Files directory location, $SUPPORT_FILES config variable, Installation and Configuration</a></h1>
Dada Mail now separates out its static files needed for the app, from the dynamic template files. These static files ship
with the app under the directory,<br />
<i>dada/static</i><br />
When you install Dada Mail using the included Installer, this entire directory will be copied to the publicly accessable directory that you specify, so that they may be served directly by the webserver. JavaScript, images and cascading style sheets will be served from this directory.<br />
In previous versions of Dada Mail, these files were served via Dada Mail, creating a new running instance of the app per request, which is slow, awkward and confusing.<br />
Both the server path, and URL to this directory will be saved in your <code>.dada_config</code> file, under the varible, <code>$SUPPORT_FILES</code>. This variable is required to be correctly configured, for Dada Mail to work.<br />
This does create an additional thing that needs to be configured for Dada Mail to be successfully installed, but we feel this extra step is worth it, for performance and for future features of the app.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="clickthrough_message_opens__etc_tracking_support_dropped_for_default_backend">Clickthrough/Message Opens, etc tracking support dropped for Default Backend</a></h1>
The Tracker plugin and all of its functionality now requires the use of one of the SQL backends.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="list_control_panel_screens">List Control Panel Screens</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="mass_mailing____send_a_message">Mass Mailing >> Send a Message</a></h2>
Options for Mass Mailing, including File Attachments, Archive Options, etc have been moved to a tabbed interface.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="membership____view">Membership >> View</a></h2>
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="breakdown_by_domain_graph">Breakdown by Domain Graph</a></h3>
The Breakdown by Domain graph, that used to be in the Tracker plugin has been moved to the <b>Membership - View screen</b>. Clicking on any of the pie slices
will perform a search on the domain you have selected.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="search_autocomplete">Search Autocomplete</a></h3>
The Subscriber search form has autocomplete capabilities, which searches and matches on email addresses<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="membership____recent_activity">Membership >> Recent Activity</a></h2>
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="subscription_trends_graph">Subscription Trends graph</a></h3>
The <b>Recent Activity</b> screen now has a graph labeled, <b>Subscription Trends</b>. This graph shows daily, as well as cumulative data on Subscriptions and Unsubscriptions on your mailing list.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="wysiwyg_editors_and_template_tags">WYSIWYG editors and Template Tags</a></h1>
In version < 6 of Dada Mail, when template tags like,<br />
<pre> <!-- tmpl_var list_settings.list_name --></pre>
are entered in the rich text (rather than source view) of the WYSIWYG editor, the "<", and, ">" characters are converted into their HTML entities, so the source of your message now looks like this:<br />
<pre> &lt;!-- tmpl_var list_settings.list_name --&gt;</pre>
Which breaks the tag, and you will see the original template tag, which will not be converted to its value.<br />
In v6, Dada Mail will look for these types of conversions, and convert them back, fixing the template tag, to be parsed correctly.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="data_cache">Data Cache</a></h1>
Dada Mail now has a data cache, for things like generated JSON files. This data cache can be managed with the new, <code>DADA::App::DataCache</code> module and can be enabled/disabled using the <code>$DADA_CACHE</code> config variable. Old cached data will be removed periodically (1 hour), automatically. The data cache is located in the,<br />
<i>.dada_files/.tmp/_dada_cache</i><br />
directory. The files, as well as the directory itself, may be safely removed at any time.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="plugins">Plugins</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="tracker">Tracker</a></h2>
The Tracker plugin has been essentially rewritten, and its features have been expanded. All charts, graphs and maps generated are now interactive and mousing over various parts of the chart/graph/map will reveal additional information. The UI itself has been redesigned, as well.<br />
The new charts/graphs/maps are powered by the Google Visualization API. Data, in the JSON format is created for Dada Mail using the Perl CPAN module,
JSON (<a href="http://search.cpan.org/~makamaka/JSON/">http://search.cpan.org/~makamaka/JSON/</a>). This module will need to be installed on your hosting platform for these charts/graphs/maps to be created.<br />
Although not part of the standard Perl Library, the module proves to be so useful, that it's usually already installed on many hosting platforms (like LWP, CGI, etc).<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="expanded_location_based_information">Expanded location-based information</a></h3>
As well as country-specific information, Tracker now supports showing information on a city-specific level.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="city_reports_by_ip_address">City Reports by IP Address</a></h3>
Reports are now generated per country, breaking down then by city, and then by individual IP address that may have caused an event,
(a message open, clickthrough, forward, archive view) and listed in chronological order.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="included_city_geo_ip_data">Included City Geo IP Data</a></h3>
Dada Mail now comes with both a country Geo IP database, as well as a city-level Geo IP database. The city-level database is fairly large - ~20 megs., but it's utility is worth its size. Geo IP data is provided by <a href="http://maxmind.com/">http://maxmind.com</a>, who also provide more accurate country/city data, on a subscription.<br />
The distro of Dada Mail is much larger - around 20 megs. compressed, rather than ~7.5 megs for v5 of Dada Mail. This additional size is mostly from the bundled city-level Geo IP database.<br />
Both the city, and country-level Geo IP databases can be found in the,<br />
<i>dada/data</i><br />
directory.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="bounce_handler">Bounce Handler</a></h2>
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="filename_change__dada_bounce_handler_pl_to_bounce_handler_cgi">Filename change: dada_bounce_handler.pl to bounce_handler.cgi</a></h3>
Make sure to update any cronjobs, links, etc.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="rules">Rules</a></h3>
The Bounce Handler Rules, used to match the type of bounced message that gets sent to the bounce handler, has been moved out of the code and into its own file, which you may find at,<br />
<i>dada/data/bounce_handler_rules.pl</i><br />
You may also copy the file, and place it in your,<br />
<i>.dada_files/.configs</i><br />
directory, make your own changes/customizations, and the Bounce Handler will use your copy, instead of what ships with Dada Mail.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="bridge">Bridge</a></h2>
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="filename_change__dada_bridge_pl_to_bridge_cgi">Filename change: dada_bridge.pl to bridge.cgi</a></h3>
Make sure to update any cronjobs, links, etc.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="list_email_mail_forwarding_support">List Email Mail Forwarding Support</a></h3>
You may now set up a List Email as a Mail Forward, that pipes a message directory to Dada Bridge, rather than as a POP3 email account, that is checked on a schedule via a cronjob. This should greatly help any lag between when the message is sent to the List Email address, and when the message is checked by Bridge, and sent out to the entire mailing list.<br />
<h3>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="clean_up_replies_filter___disabled">Clean Up Replies Filter - Disabled</a></h3>
This experimental feature doesn't work very well and has been disabled in v6.<br />
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="scheduled_mailings___deprecated">Scheduled Mailings - DEPRECATED</a></h2>
The current scheduled_mailings.pl plugin, as it currently stands, needs a rewrite and isn't currently benefitting from the advances of code style, best practices and techniques offered by the rest of Dada Mail.<br />
Unless rewritten, it will be removed in a future version of Dada Mail.<br />
<hr />
<h1>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="extensions">Extensions</a></h1>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=2118058455075556259" name="dada_digest_pl___removed">dada_digest.pl - REMOVED</a></h2>
<br />
Cheers, <br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-51460185529442944382012-07-30T19:30:00.005-07:002012-07-30T19:30:59.054-07:00Dada Mail v5.2.0 Released<br />
<br />
Hello Everyone,<br />
<br />
Dada Mail v5.2.0 has been released - install/upgrade/download it from:<br />
<br />
<a href="http://dadamailproject.com/support/documentation-5_2_0/install_dada_mail.pod.html">http://dadamailproject.com/support/documentation-5_2_0/install_dada_mail.pod.html</a><br />
<br />
The changelog is below:<br />
<br />
<span class="Apple-style-span" style="font-size: 24px; font-weight: bold;"><br /></span><br />
<span class="Apple-style-span" style="font-size: 24px; font-weight: bold;">Summary 5.2.0</span><br />
<br />
Dada Mail v5.2.0 release focuses on WYSIWYG editors, which allow you to author your HTML email messages in rich text, right from within the List Control Panel.<br />
<br />
Dada Mail now comes bundled with three different WYSIWYG editors: CKEditor, Tiny MCE and FCKeditor. KCfinder, an image/file browser/uploader is also bundled. Dragging and Dropping images to be used in your email messages is also supported in Dada Mail. All these utilities can be installed easily using the included Dada Mail Installer.<br />
<br />
We've streamlined the Send a Message and Send a Webpage screens to better utilize and more cleanly present these editors, while still allowing you full flexibility on how you author your messages: We've moved to a tabbed interface for the mailing list message, so that you can easily toggle between your HTML Version and your PlainText version, without unnecessary scrolling.<br />
<br />
If upgrading from any previous version of Dada Mail, we highly suggest Creating a new .dada_config file, when using the included Dada Mail installer, as many items in the starter .dada_config file have now changed.<br />
<br />
<br />
<br />
<h2>
Features 5.2.0</h2>
<h3>
WYSIWYG/File Browsers</h3>
<br />
Dada Mail now supports and comes bundled with the following WYSIWYG editors:<br />
<br />
<br />
<ul>
<li>CKEditor </li>
<li>Tiny MCE </li>
<li>FCKEditor </li>
</ul>
<br />
<br />
Dada Mail also comes bundled with the file browser/file upload utility called, KCFinder. This utility allows file file browsing and file (image) uploading for all three included WYSIWYG editor.<br />
<br />
<span class="Apple-style-span" style="font-size: 19px; font-weight: bold;">Dada Mail Installer Support</span><br />
<br />
The Dada Mail Installer now has the ability to configure and install all three WYSIWYG editors, as well as the file browser. Installing all these utilities is optional, but much easier than doing it manually. The editors and browser are bundled with Dada Mail in the, dada/extras/packages directory.<br />
<br />
<span class="Apple-style-span" style="font-size: 19px; font-weight: bold;">Added Support for Tiny MCE</span><br />
<br />
Along with Support for CKeditor and FCKeditor, Dada Mail now supports the Tiny MCE WYSIWYG HTML editor in its Send a Message and Send a Webpage screens.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: 19px; font-weight: bold;">Support for Drag and Drop images (in some browsers)</span><br />
<br />
Instead of having to go through the File Browser to upload an image, you can simply drag an image into one of the WYSIWYG editors. The image will then be saved in your file browser's file uploads directory and will be able to be used again for a future mass mailing.<br />
<br />
This doesn't work for all browsers, but is confirmed to be support in Firefox 14+.<br />
<br />
<br />
<br />
Discussion Lists: Experimental Support for Cleaning up long quoted replies of mailing list openings/signatures<br />
<br />
Look for the option labeled, Attempt to clean up replies in Dada Bridge.<br />
<br />
<br />
<br />
Tabbed Interface for PlainText/HTML Mailing List Messages<br />
<br />
Dada Mail now allows you to toggle between the HTML, and PlainText versions of your mailing list message with a tabbed interface, instead of showing/hiding each type.<br />
<br />
<br />
<br />
Subscription/Unsubscription Admin notices may now go to the entire mailing list<br />
<br />
It's now an option to send the Subscription and Unsubscription Notices that usually go to the List Owner, to your entire list. This could be useful for a discussion list.<br />
<br />
This feature was commissioned by David Smith for the Adytum Builders discussion list http://adytumbuilders.net/<br />
<br />
<br />
<br />
<h3>
Bugfixes 5.2.0</h3>
First Archive message shows incorrect link<br />
<br />
<a href="https://github.com/justingit/dada-mail/issues/303">https://github.com/justingit/dada-mail/issues/303</a><br />
<br />
<br />
<br />
Lack of "message_body" tag in Mailing List Message Template leads to completely blank mailing list message<br />
<br />
<a href="https://github.com/justingit/dada-mail/issues/304">https://github.com/justingit/dada-mail/issues/304</a><br />
<br />
<br />
<br />
Sending Preferences: Amazon SES has strange, blank blue box with nothing in it.<br />
<br />
<a href="https://github.com/justingit/dada-mail/issues/305">https://github.com/justingit/dada-mail/issues/305</a><br />
<br />
<br />
<br />
Dada Bridge does not run the mailing monitor, when done checking messages<br />
<br />
<a href="https://github.com/justingit/dada-mail/issues/306">https://github.com/justingit/dada-mail/issues/306</a><br />
<br />
<br />
<br />
Impossible to delete invalid-in-form email address in "Membership >> View" screen<br />
<br />
<a href="https://github.com/justingit/dada-mail/issues/307">https://github.com/justingit/dada-mail/issues/307</a><br />
<br />
<span class="Apple-style-span" style="font-size: 19px; font-weight: bold;">Changes 5.2.0</span><br />
<br />
<span class="Apple-style-span" style="font-size: 19px; font-weight: bold;">WYSIWYG Editors</span><br />
<br />
<br />
Dada Bridge: Mailing List Message Template Tags for Discussion Lists Will be, "de-Personalized"<br />
<br />
By default, the Mailing List Messages that ship with Dada Mail have template tags and links that point to various resources for subscribers of a mailing list. This includes changing the status of a subscription and logging into a subscriber's Profile. These links are personalized for the subscriber, so to avoid any additional entering of information/clicks.<br />
<br />
These links cause havoc, though, on a discussion list, where messages are replied to and the original message is often quoted, and copied with the reply, as well as forwarded to people, off the list. The once-personal links now can be clicked by a third party, initializing such things as unsubscriptions. You may edit your Mailing List Message Templates to removed this personalization, but it is another step to set up a successful mailing list.<br />
<br />
Starting with v5.2.0 of Dada Mail, these links will be, "de-Personalized" automatically for discussion lists. For example, a link that goes goes to a specific addresses' profile (or a form to log into a profile), that has their email address already embedded within the link, to pass automatically to Dada Mail:<br />
<br />
ttp://example.com/cgi-bin/dada/mail.cgi/profile_login/user/example.com<br />
<br />
will have the embedded email address removed:<br />
<br />
http://example.com/cgi-bin/dada/mail.cgi/profile_login/<br />
<br />
Similarily, Subscription and Unsubscription links:<br />
<br />
http://example.com/cgi-bin/dada/mail.cgi/u/listname/user/example.com<br />
<br />
will be changed to,<br />
<br />
http://example.com/cgi-bin/dada/mail.cgi/u/listname/<br />
<br />
To avoid problems.<br />
<br />
<br />
<br />
<h3>
FCKeditor listed as "Deprecated"</h3>
<br />
FCKeditor has now been deprecated in Dada Mail for many reasons: Internet Explorer 9 does not work well with FCKeditor, the included File Browser in FCKeditor is very buggy and has unfixed security issues and CKeditor is its natural replacement. We do not suggest using FCKeditor, but it is bundled with Dada Mail currently for backwards compatibility. We do bundle CKEditor and Tiny MCE, either of which will work better the FCKeditor.<br />
<br />
<br />
<br />
<h3>
$FCKEDITOR_URL and $CKEDITOR_URL Config variables - removed</h3>
<br />
Both the $FCKEDITOR_URL and $CKEDITOR_URL variables will not function as before - use the new $WYSIWYG_OPTIONS variable to configure these editors. Having these variables in your .dada_config file will not cause Dada Mail to error, yet.<br />
<br />
<br />
<br />
<h3>
"By default, reveal: PlainText Version|HTML Version" option removed</h3>
<br />
The Send a Message/Webpage screens now have a tabbed interface for HTML/PlainText messages, so this option has been removed. In Beatitude, both versions will be shown, by default.<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-87632672552671227962010-09-27T16:02:00.000-07:002010-09-27T16:36:45.134-07:00On making a Simple Web-based installer in PerlRecently and after 10 years of avoiding the idea, I made a web-based installer for Dada Mail.<br /><br />My original thought was, something like this isn't necessary, that the installation process had been twiddled down to changing, oh, 3 variables in a heavily documented config file and additional "power user" fancy things to do, if You Knew What You Were Doing. What could possibly be easier?<br /><br />Oh, how wrong I was - and how I never knew how wrong I was, until I've gotten some feedback on the alternative of having an installer.<br /><br />You can get a gist of how the installer works in this video:<br /><br /><br /><object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/md8NNRkjRR4?fs=1&hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/md8NNRkjRR4?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="385" width="480"></embed></object><br /><br />Basically, you pop up a tar.gz distro and a helper script that just gets things all set, you run the helper script and fill in a few things in a form - most of which are pre-filled with Best Guesses. I am not breaking new ground, here.<br /><br />BUT what I am doing is giving my users the patented PHP Xperience - and that's what they want:<br /><br />You throw up some files, you visit some stuff via your browser, you set some params and you go zoom.<br /><br />The problem with, "<span style="font-style: italic;">But, there's all these CPAN dependencies!!!</span>" was solved a long time ago in this project by only using Pure Perl modules (gets limiting in some instances) and shipping the app with an already pre-filled app-specific perllib. This also is a huge headache and the shipped-perllib is always behind, but it's better than nothing. The cpan deps service has been heaven-sent for roll-your-own-manually folks. The, "<span style="font-style: italic;">But, there's Cool Things in CPAN to do Cool Things in your App!</span>" wish is solved by just making these cools things optional. cPanel, which is what a lot of Very Cheap Web Hosts use as their platform has a web-based cpan installer, so it's even within a mortal's reach to use CPAN to do fun things.<br /><br />Anyways: here is, after a month of having the installer, some reflections:<br /><br /><span style="font-weight: bold;">The support boards aren't devoid of installation questions, but they sure are a lot quieter. </span><br /><br />There are users who are intimidated by the installer. I don't know how else I can make things easier and these users would also be intimidated by doing things manually (which is still an option). I used to be intimidated with oiling the chain on my bicycle, but it takes... I dunno, 5 minutes to learn what you need to do. I don't ever say, "Uh, Google-fu the base level how-to to, (for example) FTP a file", but I don't quite know what I need to say.<br /><br />But, the other amount of users that were intimidated doing things manually, but can also figure out the installer is the majority. Which is great - solved the problem. Now, the questions are simply bizarre edge cases dealing with weird MySQL setups on questionable hosting accounts. Happy to help.<br /><br />Since more people are having an easier time installing the program, I get the feeling that more people are installing the program, successfully, which is great. I don't have any hard facts for that one, sadly. There are a small amount of people that tell me they like the <span style="font-style: italic;">Hard Way of doing things</span>, and <span style="font-style: italic;">Why would I ever change? You're ruining my flawed work flow!</span>, and I don't really know what to tell those folks, except to try the new way, that there is a manual way and it's progress - babe. And also, the previous version is still available if you want Hell, again. I had shipped the installer as the only new feature of the current version, so there's nothing that was missing.<br /><br />Another hunch I have is that my own services to install the program are dramatically down. I can certainly graph how many installs I do per day/month/whatever, but these numbers are affected by a number of things: the economy, other competing programs, if Burning Man was particularly amazing and how long it takes someone after Labor Day to decompress, etc. This is also fine for me, because I loathe having to install the program for people: it takes a lot of time. I would rather they do it, themselves.<br /><br />When I do install the program? Guess what, I use the web-based installer too. It's that much better/faster/spiffier. I really wish I created the installer earlier, as the time it took to make the installer would have paid back sooner for the time it's saving me number. I would have like 10 years of that time back, instead of just a month, but whatchagonna do.<br /><br />But I've now raised the bar on Easiness...es and have a new problem: people who found the installer easy to use, want to upgrade just as easy. 10 years of development of a program, especially when Year 0 I knew not of the ways of Perl and Year 10 I'm still very much an amateur with a Right Hemispherical controlled mind.... things are messy. The config file format sucks, for example. And I have ten years of versions people want to upgrade from.<br /><br />Should be interesting.<br /><br /><span style="font-weight: bold;">Some notes on the design of the installer: </span><br /><br />I basically decided to make the installer as separate from the main program as possible, meaning it has its own library files, it's own template files, it's own <strike>testing suite</strike> (coming soon, I promise!). It does not use a framework, but uses the modulino approach. Things are fairly tidy.<br /><br />It's written in a procedural design, because installations and configurations have steps. See? I just listed two of them. I made wrappers around things that deal with system calls - copying/removing files/directories, for example. I was thinking there could/would/should be edge cases for different OS's, but I really haven't found any, but I guess it still gives breathing room for someone much smarter than me to move in and make a better version of whatever I've botched. I did start with just using back ticks to system calls and replace those with perlish alternatives.<br /><br /><br />So. I'm not sure what stops all of us from making similar web-based installers for our web-apps. I am coming from a field (Art) and a preference for visual things, so I never really gotten a handle on system-admin type of tasks. The trend, it seems, in software is less, Give me as many options to roll my own doo-dad as I can have" and more, "<span style="font-style: italic;">Just freakin' work. And On my phone. When my 2-y/o uses it."</span> I'm a little embarrassed at how much of the code I have is simply crap boilerplate to look up boring things about someone's environment to install. It seems that can all be sweeped under the floor and get some shared code. But then again, there's the rub, huh? If its shared code it's on CPAN, and then, how do you get the CPAN module, without a major compromise? And someone will be brilliant and write it in Moose (which is also, sincerely, brilliant) and there goes the baby, with the bathwater.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-76280518240271913632010-03-07T21:28:00.001-08:002010-03-07T21:28:26.437-08:00<div id="archived_message_body"> <p>Dada Mail Four Point Zero Point Three Released. Super Duper UTF-8/Unicode Support </p><hr /> <h1><a name="section_1">Download: </a></h1> <p> <a href="http://dadamailproject.com/">http://dadamailproject.com</a> </p><h1><a name="section_2">What's New</a></h1> <p>We've been working really really hard to get the UTF-8/Unicode support working well in Dada Mail and this release, we really - no foolin' this time, think we've nailed it. </p><p>If you require character set support that's a little more than what's usually found in Latin-based languages, well, this is the release for you. We're going to build localization/internationalization support into Dada Mail, starting with this release. That means, we're going to start translating Dada Mail into multiple languages. </p><p>This release also has some pleasant bug-fixes. We couldn't have done it without your feedback. </p><h1><a name="section_3">Pro Dada Four - Ever: $44 </a></h1> <p>There's only one more week to take advantage of this deal. After that? Gone. </p><p>Purchase Pro Dada for a special price of Forty-Four Dollars and your subscription to download Pro Dada and the Dada Mail Manual lasts Forever. </p><p>Pro Dada subscriptions are usually for a year. This offer extends your subscription for the entire life of the Dada Mail Project. </p><p>Purchase at: </p><p> <a href="http://dadamailproject.com/purchase/pro.html">http://dadamailproject.com/purchase/pro.html</a> </p><p>This irrational offer lasts until pi day (3/14/2010) </p><h1><a name="section_4">Pro Dada Four Installed - $88</a></h1> <p>Get Pro Dada installed by us or get any current Dada Mail upgraded to Pro Dada Mail Four, for $88 (regularly $100). We'll keep upgrading it at your request for a year, but you'll have access to the Pro Dada Download and Dada Mail Manual for the life of the Dada Mail project. </p><p>Request an Install or Upgrade: </p><p> <a href="http://dadamailproject.com/installation/request.html">http://dadamailproject.com/installation/request.html</a> </p><p>This irrational offer also only lasts until pi day (3/14/2010) - you have week left to submit that installation request. </p><h1><a name="section_5">Dada Mail Turns Ten in 2010</a></h1> <p>The Dada Mail Project started ten years ago in December of 1999 as a small curiosity and has gradually evolved and developed into an extremely popular programming and conceptual art project. Happy Birthday, Dada Mail. </p><p>Dada Mail Four is our latest release. Thanks for everyone's thoughtful feedback in this year-long development effort. </p><p>We couldn't have done it without you. </p><p>We're looking forward to receiving your feedback on Dada Mail Four. </p><p>Good luck! </p><p>Justin J<br />Lead Dadaist<br /><a href="http://dadamailproject.com/">http://dadamailproject.com</a> </p> <p>Dada Mail Change Log for version 4.0.3 </p><hr /> <h1><a name="section_6">Unicode/UTF-8 Work</a></h1> <p>We have worked very, very hard to get Dada Mail working with UTF-8/Unicode. </p><p>We think we did a pretty good job and you'll have a most amazing experience when comparing this version to any previous version of Dada Mail (ever), but there may be tiny things still to work out. </p><p>We need to know about them, don't be shy! </p><h1><a name="section_7">SQL table schema changes!</a></h1> <p>People who upgrade to 4.0.3 (and any version afterwards, until things change!) should note that the MySQL and PostgreSQL Table Schemas have changed! </p><p>You may need to update your own tables, to support UTF-8 (if they aren't already in that encoding). </p><h1><a name="section_8">See Also:</a></h1> <p>If you're upgrading, please read over the updated UTF-8/Unicode FAQ: </p><p><a href="http://dadamailproject.com/support/documentation/features-UTF-8.pod.html">http://dadamailproject.com/support/documentation/features-UTF-8.pod.html</a> </p><p>If you're doing a new install, there's nothing you need to know, Dada Mail should work well out of the box in re: to UTF-8/Unicode stuff. </p><p>Changes to Default List Settings<br />We've changed a few of the default list settings, hopefully so that everyone has a more pleasant experience, right off the bat: </p><h1><a name="section_9">Activate Black List</a></h1> <p>We've enabled the setting to active the Black List, by default. </p><p>We're also enabling the below settings: </p><ul><li>Move Unsubscribed Subscribers Automatically to the Black List </li><li>Continue to Allow Subscriptions From Subscribers of Black Listed Addresses</li></ul> <p>You still have the option to change new lists to the previous behavior and already created lists will have their previous behavior, if Black List Settings have already been edited. </p><h1><a name="section_10">Print List-Specific Headers option Removed</a></h1> <p>The option, Print List-Specific Headers has been removed from, <em>Mail Sending -Advanced Sending Preferences</em> has been removed, <em>but</em> the functionality has not. All mailing list messages will have these headers. </p><h1><a name="section_11">Send Unsubscription Confirmation Emails (Closed-Loop Opt-Out) - disabled by default</a></h1> <p>Send Unsubscription Confirmation Emails (Closed-Loop Opt-Out) has been disabled by default (you can still enable it) </p><p>This option, when enabled, requires that when someone wants to unsubscribe, they have to confirm this unsubscription by clicking on the unsubscription confirmation link in a URL sent their subscribed address. </p><p>When disabled (the new default), they simply have to fill out the subscribe/unsubscribe form. </p><h1><a name="section_12">Subscription and Unsubscription links now include an Email Address</a></h1> <p>When available, both the Subscription and Unsubscription links will have the potential subscriber's (or unsubscriber's) email address in the link itself, so that the user does not have to do the two-step of first following the link and then typing in their email address. </p><p>These links are created per-subscriber (or potential sub/unsub), when you use the: </p><p> <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/s/dada_announce/example/example.com/">http://dadamailproject.com/cgi-bin/dada/mail.cgi/s/dada_announce/example/example.com/</a> </p><p>or, </p><p> <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/u/dada_announce/example/example.com/">http://dadamailproject.com/cgi-bin/dada/mail.cgi/u/dada_announce/example/example.com/</a> </p><p>tags. Previously, these tags only provided a link to the subscription/unsubscription form, without the email address embedded within the link itself. There is no way to revert this behaviour, but you can still roll your own links, like this: </p><p>Subscription Link: </p><p> <!-- tmpl_var PROGRAM_URL -->/s/<!-- tmpl_var list_settings.list --> </p><p>Unsubscription Link: </p><p> <!-- tmpl_var PROGRAM_URL -->/u/<!-- tmpl_var list_settings.list --> </p><p>Unsubscription Links Now Mandatory for Mass Mailing Messages Dada Mail will now do a quick check to make sure that there is a Dada Mail Unsubscription link in your mass mailing messages, before sending them out. </p><p>If one is not found, one will be automatically appended to the end of your message. </p><p>It will not be very fancy. </p><p>We suggest that you make sure that you have a real, valid, Dada Mail unsubscription link in your Mailing List Messages. </p><p>Bug Fixes 4.0.3 </p><ul><li>Send newest archived message may have outdated header information</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/30">http://github.com/justingit/dada-mail/issues/issue/30</a> </p><ul><li>pop3 username/password not saved when "Save, Then Test..." button pressed in Sending Preferences</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/29">http://github.com/justingit/dada-mail/issues/issue/29</a> </p><ul><li>Beatitude: Months are listed out of order</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/28">http://github.com/justingit/dada-mail/issues/issue/28</a> </p><ul><li>profile field names can contain more than just ascii letters, numbers and underscores</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/27">http://github.com/justingit/dada-mail/issues/issue/27</a> </p><ul><li>list short names can contain more than just ascii letters, numbers and underscores</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/26">http://github.com/justingit/dada-mail/issues/issue/26</a> </p><ul><li>Beatitude: Scheduled List Not in Any Useable Order?</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/16">http://github.com/justingit/dada-mail/issues/issue/16</a> </p><ul><li>Dada Bridge: Spam Assassin Level Picker isn't available</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/21">http://github.com/justingit/dada-mail/issues/issue/21</a> </p><ul><li>Sending Preferences don't correctly state if you can use Use Secure Sockets Layer (SSL) for POP-before-SMTP</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/24">http://github.com/justingit/dada-mail/issues/issue/24</a> </p><ul><li>Double Subscriptions when using List Invitation</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/23">http://github.com/justingit/dada-mail/issues/issue/23</a> </p><ul><li>Archived messages not templated out in publicly displayed archives</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/20">http://github.com/justingit/dada-mail/issues/issue/20</a> </p><p>*Link to edit subscriber information broken when using the search </p><p><a href="http://github.com/justingit/dada-mail/issues/issue/19">http://github.com/justingit/dada-mail/issues/issue/19</a> </p><ul><li>Unsubsciption Notice to List Owner doesn't have subscriber (profile) fields</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/18">http://github.com/justingit/dada-mail/issues/issue/18</a> </p><ul><li>Disabled Menu items return server error when using the, "Classic" session type</li></ul> <p><a href="http://github.com/justingit/dada-mail/issues/issue/15">http://github.com/justingit/dada-mail/issues/issue/15</a> </p> </div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-50221316008462081692010-02-23T22:33:00.000-08:002010-02-23T22:38:24.578-08:00Experimental Dada Mail w/unicode ¡Support! Released(this is a repost from <a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dadadev/20100224011503/">here</a>, 'cause I'm pretty stoked on it)<br /><br /><br />This is the first step in the localization project, since we can't very well translate Dada Mail if Dada Mail can't use the translations available.<br /><br />I have to let this project rest for a little bit (and collect my wits - it was a very difficult step!) but any and all feedback is welcome, if you'd like to give this a spin - bug reports/problems of any kind are very much appreciated.<br /><br />This version of Dada Mail should basically be able to support any language that can in the unicode characters set and UTF-8 encoding. Which, should be, well, a lot of them. It doesn't (Dada Mail), but where it fails? I don't know - but it's a good time to test and see where it's wrong.<br /><br />For simple Euro-centric stuff, like this:<br /><br /> Je peux manger du verre, ça ne me fait pas mal.<br /><br />It should be fine. For something a little more wild:<br /> <br /> أنا قادر على أكل الزجاج و هذا لا يؤلمني.<br /><br />(which should be Arabic)<br /><br />Well, I can only go on if something visually looks correct :) Even this email is sort of a test - I don't know if it's going to work, or not - so, fingers crossed! If it does - we're on a good track, since Dada Bridge taking a random email, having it go through the system that's mostly tested using a very specific way of creating emails and coming out readable on the other side is a great big step - not even talking about the online archive, rss/atom feeds, twitter thingie, etc, etc, etc.<br /><br />Here's the download to the version I'm now running at the Dada Mail support site:<br /><br /><a href="http://github.com/downloads/justingit/dada-mail/dada-4_0_2-unicode.zip"> http://github.com/downloads/justingit/dada-mail/dada-4_0_2-unicode.zip</a><br /><br /><a href="http://github.com/downloads/justingit/dada-mail/dada-4_0_2-unicode.tar.gz"> http://github.com/downloads/justingit/dada-mail/dada-4_0_2-unicode.tar.gz</a><br /><br />If you want to check it out via github, the branch is at:<br /><br /><a href="http://github.com/justingit/dada-mail/tree/charset_work"> http://github.com/justingit/dada-mail/tree/charset_work</a><br /><br />To grab it with git, you have to do this:<br /><br /><br />git clone git://github.com/justingit/dada-mail.git<br />cd dada-mail<br />git fetch<br />git checkout --track -b your_local_branch_name origin/charset_work<br /><br /><br />Here's the explanation of all that:<br /><br /><a href="http://groups.google.com/group/github/browse_thread/thread/71f944b925467ab6">http://groups.google.com/group/github/browse_thread/thread/71f944b925467ab6</a><br /><br />There's a guide of what to expect with Dada Mail and unicode/UTF-8 you can read here:<br /><br /><a href="http://dadamailproject.com/support/documentation-4_0_2-unicode/features-UTF-8.pod.html"> http://dadamailproject.com/support/documentation-4_0_2-unicode/features-UTF-8.pod.html</a><br /><br />Which I'll paste the contents of at the end of this message - but you may also want to compare it to the version of this doc for 4.0.2 STABLE:<br /><br /><a href="http://dadamailproject.com/support/documentation-4_0_2/features-UTF-8.pod.html"> http://dadamailproject.com/support/documentation-4_0_2/features-UTF-8.pod.html</a><br /><br />(Long story short: 4.0.2 UTF-8/Unicode Support: "uhh...")<br /><br />And, that's about it. This was a hard part of the project, since this is a 10+ y/o codebase - it very much pre-dates even unicode/UTF-8 support in Perl itself, so there's a reason, I guess, why the program was in such bad shape when it came to support it. Many,<br /><br />many many bugs showed themselves, once this feature was asked for. I think a great majority of them have been solved.<br /><br />Give it a spin if this interests you and if I can help out with anything, let me know,<br /><br /><br />--<br />Introduction<br /><br />Dada Mail can speak UTF-8 and almost expects that everything else around it does, too.<br /><br />That means:<br /><br /> • It treats everything it handles as UTF-8<br /> • Everything it returns is in UTF-8<br />How To Have a Pleasant Experience<br /><br />If you're installing Dada Mail for the first time, there's nothing you'll need to do, but below are some great guidelines on how to keep your lists configured, so you continue to have a good experience.<br /><br />If you're upgrading, make sure your configuration reflects the advice below.<br /><br />It's heavily advised to keep everything in Dada Mail speaking UTF-8 without any real exceptions.<br /><br />Config Variable: $HTML_CHARSET<br /><br />By default, the config variable, $HTML_CHARSET is set to, UTF-8<br /><br />Keep it that way, same case (UTF-8) - same everything.<br /><br />Dada Mail is only tested with the charset set this way.<br /><br />Advanced Sending Preferences<br /><br />Default Character Set<br /><br />Set this as, UTF-8 UTF-8<br /><br />Default Plain Text/HTML Message Encoding<br /><br />There's really only a few choices recommended for Dada Mail.<br /><br /> • 8bit<br />Should work.<br /><br /> • quoted-printable<br /><br />If you have any trouble with 8bit, try quoted-printable. Because of the amount of time that Dada Mail creates, tweaks, formats and templates out email messages, the encoding can potentially get mucked up.<br /><br />This potential mucking-up is mitigated when Dada Mail uses quoted-printable encoding internally. This should be the default for email messages.<br /><br />Encode Message Headers<br /><br />Have this option checked.<br /><br />SQL Backends<br /><br />Database<br /><br />PostgreSQL<br /><br />Encoding for PostgreSQL databases is done when the database is created - make sure to create your database with a, UTF-8 encoding, like so:<br /><br />CREATE DATABASE dadamail WITH ENCODING 'UTF-8'<br />MySQL<br /><br />Nothing you'll have to do.<br /><br />SQLite<br /><br />Nothing you'll have to do.<br /><br />DBM Files<br /><br />DBM Files have no encoding support, but Dada Mail knows this and compensates.<br /><br />Schema<br /><br />MySQL<br /><br />The MySQL schemas are set to create tables with an encoding of, UTF-8<br /><br />PostgreSQL<br /><br />Nothing has changed.<br /><br />SQLite<br /><br />Nothing has changed.<br /><br />Drivers<br /><br />The current support SQL backends, mysql (MySQL), Pg (PostgreSQL) and SQLite all have different ways to somewhat, "enable" their UTF-8 support.<br /><br /> • MySQL<br />add,<br /><br />mysql_enable_utf8 => 1,<br />has been added to the $DBI_PARAMS hashref.<br /><br /> • PostgreSQL<br />add,<br /><br />pg_enable_utf8 => 1,<br />has been added to the $DBI_PARAMS hashref.<br /><br /> • SQLite<br />add,<br /><br />sqlite_unicode => 1<br />has been added to the $DBI_PARAMS hashref.<br /><br />No explicit encoding/decoding is done in Dada Mail when saving/retrieving data. Hopefully, the drivers are UTF-8-aware enough.<br /><br />Plugins/Extensions<br /><br />The Plugins and Extensions that come with Dada Mail have not been as thoroughly tested as the main program. There's still warts.<br /><br />Dada Bridge<br /><br />Dada Bridge has a unique position needing to handle a lot of different stuff thown at it and deal with it gracefully. Dada Mail does, in fact, handle, any realistic character set/encoding you throw at it, but Dada Mail will convert messages it receives to its internal format, before it resends it out to your list.<br /><br />This means the encoding of your choice (8bit or quoted-printable) and the charset of your choice (as long as your charset is, UTF-8)<br /><br />Upgrading<br /><br />You are potentially going to have problems.<br /><br />Its possible that, since List Settings were never decoded/encoded correctly in past versions, they'll show up the program (once you've upgrade) incorrectly. The easiest thing to do is to edit the mistakes and resave the information. For most of the program, you're going to have to manually export the information and re-import it with the correct encoding, sadly. Dada Mail will probably fail gracefully with old information, but it's possible that you'll see squiggly charaters, instead of what you want to see. There's nothing in Dada Mail that will stop this from happening. If you experience it (from old information), we're not going to count it as a bug, but rather a known issue.<br /><br />Problems?<br /><br />Please let us know via the Support Boards:<br /><br /><a href="http://dadamailproject.com/support/boards/">http://dadamailproject.com/support/boards/</a><br /><br />Or the developer mailing list:<br /><br /><a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dadadev/">http://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dadadev/</a><br /><br />Thanks!<br /><br />See Also:<br /><br /> • The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)<br /><br /><a href="http://www.joelonsoftware.com/articles/Unicode.html">http://www.joelonsoftware.com/articles/Unicode.html</a><br /><br /> • perlunitut - Perl Unicode Tutorial<br /><br /><a href="http://perldoc.perl.org/perlunitut.html">http://perldoc.perl.org/perlunitut.html</a><br /><br /> • perlunifaq - Perl Unicode FAQ<br /><br /><a href="http://perldoc.perl.org/perlunifaq.html">http://perldoc.perl.org/perlunifaq.html</a><br /><br /><br /><br />--<br /><br />Post:<br />mailto:dadadev@dadamailproject.com<br /><br />Unsubscribe:<br /><a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/u/dadadev/">http://dadamailproject.com/cgi-bin/dada/mail.cgi/u/dadadev/</a><br /><br />List Information:<br /><a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dadadevhttp://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dadadev">http://dadamailproject.com/cgi-bin/dada/mail.cgi/list/dadadev</a><br /><br />Archive:<br /><a href="http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dadadev">http://dadamailproject.com/cgi-bin/dada/mail.cgi/archive/dadadev</a><br /><br />Developer Info:<br /><a href="http://dev.dadamailproject.com">http://dev.dadamailproject.com</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-12171820460349905002010-02-20T14:19:00.001-08:002010-02-20T15:16:51.260-08:00Perl HTML::Template and UTF-8 UnicodeHTML::Template does not support file encoding:<br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br />use HTML::Template;<br />my $template = HTML::Template->new(<br />filehandle => *DATA,<br />);<br />print Encode::encode('UTF-8', $template->output);<br />__DATA__<br />¡™£¢∞§¶•ªº<br /></pre><br /><span style="font-style: italic;">prints, ¡™£¢∞§¶•ªº (or something like that!)<br /><br /></span>In the example above, this makes sense, since we're printing on an open filehandle (even if it's only to our magical, DATA) that we didn't put a file layer filter thingy to. That's easy to fix:<br /><br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br /><br />binmode DATA, ':encoding(UTF-8)';<br /><br />use HTML::Template;<br />my $template = HTML::Template->new(<br /> filehandle => *DATA,<br />);<br />print Encode::encode('UTF-8', $template->output);<br />__DATA__<br />¡™£¢∞§¶•ªº<br /></pre> <span>prints</span><span style="font-style: italic;">, ¡™£¢∞§¶•ªº</span>, yay!<br /><br /><br />This also works if we want to just pass a reference to a scalar to HTML::Template:<br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br />my $content = "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}";<br />use HTML::Template;<br />my $template = HTML::Template->new(<br /> scalarref => \$content,<br />);<br />print Encode::encode('UTF-8', $template->output);<br /></pre> <span>prints</span><span style="font-style: italic;">, ¡™£¢∞§¶•ªº</span>, yay!<br /><br />This doesn't work, if we want to just give it a name of a template file. This is really useful, since HTML::Template has a feature to allow you to search through a file structure (or at least an array of directories, looking for the file).<br /><br />And this is where encoding madness begins.<br /><br />Cause I know what you're thinking, just treat HTML::Template's output like information that's coming from outside your program (since, if you're using a template *file*, it kinda is).<br /><br />So, all you need to do is decode (this is the WRONG WAY to solve the problem, but let's just make that mistake...) the return value of ->output, like this:<br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br />my $content = "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}";<br /><br />my $filename = 'utf8string.tmpl';<br /><br />open my $fh, '>:encoding(UTF-8)', $filename or die $!;<br />print $fh $content;<br />close $fh;<br /><br />use HTML::Template;<br />my $template = HTML::Template->new(<br /> filename => $filename,<br />);<br /><br />my $output = $template->output;<br />$output = Encode::decode('UTF-8', $output);<br /><br />print Encode::encode('UTF-8', $output);<br /></pre><br /><br />prints, <em>¡™£¢∞§¶•ªº</em>. Yes.<br /><br />But... what if you have a variable (it <span style="font-style: italic;">is</span> a templating system) and the variable in the param() you pass has UTF-8 strings? MUAHAHA!<br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br />my $content = "<br /><!-- tmpl_var one --><br />\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}<br />";<br /><br />my $filename = 'utf8string.tmpl';<br /><br />open my $fh, '>:encoding(UTF-8)', $filename or die $!;<br />print $fh $content;<br />close $fh;<br /><br /><br />use HTML::Template;<br />my $template = HTML::Template->new(<br /> filename => $filename,<br />);<br />$template->param(<br />one => "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}",<br />);<br /><br />my $output = $template->output;<br />$output = Encode::decode('UTF-8', $output);<br /><br />print Encode::encode('UTF-8', $output);<br /></pre><br /><span style="font-weight: bold;">Cannot decode string with wide characters at /System/Library/Perl/5.10.0/darwin-thread-multi-2level/Encode.pm line 162.</span><br /><br /><br />Bahahaha!<br /><br />Take those decode/encode lines (I know it looks strange to one, right after the other ) and you'll still get a weird output:<br /><br /><pre><br />¡™£¢∞§¶•ªº<br />¡™£¢∞§¶•ªº<br /></pre><br /><br />Darned if you do/don't. Those two lines should have the same string. They don't. No amount of encoding/decoding is going to help.<br /><br /><br />The trick, other than tweaking HTML::Template's source to include file filter layer thingamabobs, is to decode the contents of the file it opens up.<br /><br />How to do that.<br /><br />Trolling through the HTML::Template mailing list archives leads to the idea of using a HTML::Template filter that matches everything, that then does our decoding:<br /><br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br />use Encode;<br />my $content = "<br /><!-- tmpl_var one --><br />\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}<br />";<br /><br />my $filename = 'utf8string.tmpl';<br /><br />open my $fh, '>:encoding(UTF-8)', $filename or die $!;<br />print $fh $content;<br />close $fh;<br /><br /><br />use HTML::Template;<br />my $template = HTML::Template->new(<br /> filename => $filename,<br /> filter => [<br /> { sub => \&decode_str, format => 'scalar' },<br /> ],<br />);<br />$template->param(<br />one => "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}",<br />);<br /><br />my $output = $template->output;<br /><br /><br />print Encode::encode('UTF-8', $output);<br /><br /><br /><br />sub decode_str {<br />my $ref = shift;<br />${$ref} = Encode::decode('UTF-8', ${$ref});<br />}<br /></pre><br />This sort of lines up all the data to be UTF-8 encoded and aware and all that stuff that the unicodefaqthingy perldoc tells you to do.<br /><br />But, oh, it gets better.<br /><br />DON'T use that filter trick thing if you're using a scalarref, or a properly encoded file handle! You'll get a nice error, like this:<br /><br /><span style="font-weight: bold;">HTML::Template->new() : fatal error occured during filter call: Cannot decode string with wide characters at /System/Library/Perl/5.10.0/darwin-thread-multi-2level/Encode.pm line 162.</span><br /><span style="font-weight: bold;">at /Library/Perl/5.10.0/HTML/Template.pm line 1697</span><br /><span style="font-weight: bold;">HTML::Template::_init_template('HTML::Template=HASH(0x1008aafb8)') called at /Library/Perl/5.10.0/HTML/Template.pm line 1238</span><br /><span style="font-weight: bold;">HTML::Template::_init('HTML::Template=HASH(0x1008aafb8)') called at /Library/Perl/5.10.0/HTML/Template.pm line 1124<br /><br /></span><br /><br />Brilliant.<br /><br /><br />So I don't know what the best advice is to give. If you're passing the template as a scalarref, DON'T use that filter, unless you want to, perhaps encode your template beforehand (which makes little sense?)<br /><br />If it's a filename, use that filter trick perhaps (or edit the sourcecode of HTML::Template).Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-2118058455075556259.post-90735541693688798262010-02-15T16:48:00.001-08:002010-02-15T17:24:59.572-08:00Perl, UTF-8 Email Messages, MIME::Enity and QuotedPrintable encoding<p>Some findings after much bashing of head:</p><pre><br />#!/usr/bin/perl -w<br />use strict;<br /><br />use MIME::Entity;<br />use Encode;<br /><br /># My UTF-8 string -<br /># ¡™£¢∞§¶•ªº<br /># Basically using Mac OS X, just hold down the alt/option key and hit the 1 through 0 keys, in succession:<br />#<br />my $content = "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}";<br /><br /># Build the message, using MIME::Entity.<br /># MAKE SURE TO ALWAYS encode('UTF-8', 'string') BEFORE ADDING<br /># Always.<br /><br />my $pt_entity = MIME::Entity->build(<br /> Type => 'text/plain',<br /> Data => Encode::encode('UTF-8', $content),<br /> Encoding => 'quoted-printable',<br />);<br /><br /><br /><br /># MAKE SURE TO ALWAYS decode('UTF-8', 'string') BEFORE WORKING WITH STRING<br /># Always.<br />my $new_content = $pt_entity->bodyhandle->as_string;<br />$new_content = Encode::decode('UTF-8', $new_content);<br /><br /># For example, we're just going to reverse it:<br />$new_content = reverse($new_content);<br /><br /><br /><br /><br />my $io = $pt_entity->bodyhandle->open('w');<br /><br /># YES. You will will need to encode content using the bodyhandle. Always.<br /># Always.<br /><br />$new_content = Encode::encode('UTF-8', $new_content);<br />$io->print($new_content); <br />$io->close;<br />$pt_entity->sync_headers(<br /> 'Length' => 'COMPUTE',<br />'Nonstandard' => 'ERASE'<br />);<br /><br /><br /># And, that's it.<br /><br /><br /><br /># Before using the content, decode<br /># Always.<br />my $result = $pt_entity->bodyhandle->as_string;<br />$result = Encode::decode('UTF-8', $result);<br /><br /><br /># Always encode, before printing.<br /># Always.<br />#<br /># prints, ºª•¶§∞¢£™¡<br />print Encode::encode('UTF-8', $result);<br /></pre><br /><br />The trick is to always, always, always encode your data, before creating any sort of entity using MIME::Entity and to always, always always decode the data you get using <code>bodyhandle()</code><br /><br />This workflow is strange, since you're told not to encode data, until you're ready to print it. I suspect there's some weird IO::File stuff going on with MIME::Entity (and friends), or, want to think of saving binary data, instead of characters when creating MIME stuff. I don't know.<br /><br />If you do not encode before, MIME::Entity will barf, when using the quoted/printable encoding, but will probably be just fine with, "8bit" encoding.<br /><br />This was a huge headache to figure out.<br /><br />This will all seem to work out, if you don't do that first encode:<br /><br /><pre><br />#!/usr/bin/perl -w<br />use strict;<br /><br />use lib qw(/Users/justin/Documents/DadaMail/git/dada-mail/dada/DADA/perllib);<br /><br />use MIME::Entity;<br />use Encode;<br /><br /># My UTF-8 string -<br /># ¡™£¢∞§¶•ªº<br /># Basically using Mac OS X, just hold down the alt/option key and hit the 1 through 0 keys, in succession:<br />#<br />my $content = "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}";<br /><br /># Build the message, using MIME::Entity.<br /># MAKE SURE TO ALWAYS encode('UTF-8', 'string') BEFORE ADDING<br /># Always.<br /><br />my $pt_entity = MIME::Entity->build(<br /> Type => 'text/plain',<br /># Data => Encode::encode('UTF-8', $content),<br /> Data => $content,<br /> Encoding => 'quoted-printable',<br />);<br /><br />my $s = $pt_entity->bodyhandle->as_string;<br /><br />$s = Encode::decode('UTF-8', $s);<br /><br /># Let's do a little string manip:<br />$s = reverse($s);<br /><br />$s = Encode::encode('UTF-8', $s);<br /><br />print $s;<br /></pre><br /><code><strong><br />Cannot decode string with wide characters at /System/Library/Perl/5.10.0/darwin-thread-multi-2level/Encode.pm line 162.<br /><br />exception_handler::die in Encode.pm at line 162<br />Encode::decode in test7.pl at line 28<br /><br /></strong><br /></code><br /><br /><br /><br />So do that first encode, please. If you don't follow this formula, your prog may work, until that last encode:<br /><br /><br /><pre> <br />#!/usr/bin/perl -w<br />use strict; <br /><br />use lib qw(/Users/justin/Documents/DadaMail/git/dada-mail/dada/DADA/perllib); <br /><br />use MIME::Entity; <br />use Encode; <br /><br /># My UTF-8 string - <br /># ¡™£¢∞§¶•ªº<br /># Basically using Mac OS X, just hold down the alt/option key and hit the 1 through 0 keys, in succession: <br />#<br />my $content = "\x{a1}\x{2122}\x{a3}\x{a2}\x{221e}\x{a7}\x{b6}\x{2022}\x{aa}\x{ba}";<br /><br /># Build the message, using MIME::Entity. <br /># MAKE SURE TO ALWAYS encode('UTF-8', 'string') BEFORE ADDING<br /># Always. <br /><br />my $pt_entity = MIME::Entity->build(<br /> Type => 'text/plain', <br /># Data => Encode::encode('UTF-8', $content),<br /> Data => $content, <br /> Encoding => 'quoted-printable',<br /> );<br /><br />my $s = $pt_entity->bodyhandle->as_string; <br /><br /># NAW, we don't need that<br /># $s = Encode::decode('UTF-8', $s); <br /><br /># Let's do a little string manip: <br />$s = reverse($s); <br /><br /># Well, that's silly! We don't need that one, either! <br /># $s = Encode::encode('UTF-8', $s); <br /><br />print $s;<br /></pre> <br /><br /><code><strong> <br />Wide character in print at /Users/justin/Desktop/test7.pl line 37.<br /></strong></code> <br /><br />And, you will do what I do, and bang your head, some more. <br /><br />I couldn't fine any info on how to handle things like MIME::Entity and UTF-8 encoding, in the excellent articles available such as this one: <br /><br /><a href="http://ahinea.com/en/tech/perl-unicode-struggle.html">http://ahinea.com/en/tech/perl-unicode-struggle.html</a><br /><br />and, <br /><br /><a href="http://perlgeek.de/en/article/encodings-and-unicode">http://perlgeek.de/en/article/encodings-and-unicode</a><br /><br />and, <br /><br /><a href="http://juerd.nl/site.plp/perluniadvice">http://juerd.nl/site.plp/perluniadvice</a><br /><br /><br />I have this article labeled as, "do not trust" <br /><br /><a href="http://kbinstuff.googlepages.com/perl,unicodeutf8,cgi.pm,apache,mod_perla">http://kbinstuff.googlepages.com/perl,unicodeutf8,cgi.pm,apache,mod_perla</a><br /><br />Because it states, <br /><blockquote><br />6.1. Encode::encode/decode<br /><br />For start, you should avoid using Encode::encode/decode/from_to to the greatest possible extent in your scripts. This will only lead to great confusion later. You may think you have gotten everything to work, but then a week later, you shall only add a little more functionality to your work and suddenly, everything falls apart and doodles will appear on your web pages.</blockquote> <br /><br /><br />I guess I understand what they mean - but you'll need to encode your UTF-8 stuff before it exits your program. Always. And, you have to decode UTF-8 info that goes out of your program. Always. How do you do this? Uh-huh, the Encode module. <br /><br />Like it says in the perldoc for unicode. So, I don't know what this page is yabbering about. I'm sure, behind the scense, Encode is used when open files with a specific encoding: <br /><br /><a href="http://perldoc.perl.org/perluniintro.html#Unicode-I/O">http://perldoc.perl.org/perluniintro.html#Unicode-I/O</a><br /><br />Which, by the way of features, is a pretty rad one.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-83426716040731663212009-08-27T22:49:00.000-07:002009-08-27T22:54:26.270-07:00ANNOUNCE: Dada Mail 3.1 alpha 3 Released<span style="font-size:130%;"><span style="font-style: italic;font-size:85%;" >(I thought I'd re-post this announcement, since I don't think many people in the perl community really know about this large project. It IS NOT Modern Perl written, as it dates back to even before Perl 5.6, but it's a very large and complex Perl program, that's still sorta/kinda easy to install. (Royal) we try.</span><br /><br />Dada Mail 3.1 alpha 3 Released<br /></span><br />After a month and a half of more development from the last release, Dada Mail 3.1 alpha 3 has been released.<br /><br /><span style="font-size:130%;">Download</span><br /><br />tar.gz:<br /><br /> <a href="http://github.com/justingit/dada-mail/tarball/v3_1_0_alpha3-08_26_09">http://github.com/justingit/dada-mail/tarball/v3_1_0_alpha3-08_26_09</a><br /><br />zip:<br /><br /> <a href="http://github.com/justingit/dada-mail/zipball/v3_1_0_alpha3-08_26_09">http://github.com/justingit/dada-mail/zipball/v3_1_0_alpha3-08_26_09</a><br /><br /><span style="font-size:130%;">Changes</span><br /><br />To get caught up in what's changed, please see:<br /><br />Dada Mail 3.0 to 3.1 Changelog<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/changes_3.0_3.1.pod.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/changes_3.0_3.1.pod.html</a><br /><br />Dada Mail 3.0 to Dada Mail 3.1 Guide<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/dada3_0_to_dada3_1.pod.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/dada3_0_to_dada3_1.pod.html</a><br /><br />An overview of some of the new features, including:<br /><br />Dada Profiles (BIG Feature)<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-profiles.pod.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-profiles.pod.html</a><br /><br />Multiple Mailing List Sending<br /><br /> <a href="http:///dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-multiple_list_sending.pod.html">http:///dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-multiple_list_sending.pod.html</a><br /><br />(VERY initial) UTF-8 Support<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-UTF-8.pod.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/features-UTF-8.pod.html</a><br /><br />If you plan on upgrading, please also see the 3.0 to 3.1 migration tool:<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/dada_3_to_dada_3.1_sql.pl.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/dada_3_to_dada_3.1_sql.pl.html</a><br /><br />which should make things a little more pleasant.<br /><br />There's also more development docs for the new API, including:<br /><br />DADA::Profile<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile.pm.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile.pm.html</a><br /><br />DADA::Profile::Fields<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile_Fields.pm.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile_Fields.pm.html</a><br /><br />DADA::Profile::Session<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile_Session.pm.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/Profile_Session.pm.html</a><br /><br />DADA::ProfileFieldsManager<br /><br /> <a href="http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/ProfileFieldsManager.pm.html">http://dadamailproject.com/support/documentation-dada-3_1_0-alpha_3/ProfileFieldsManager.pm.html</a><br /><br /><span style="font-size:130%;">What is Dada Mail?</span><br /><br />Dada Mail is a completely contemporary, mature and intuitive web-based e-mail list management system, which runs on most any Unix-like hosting account that can run custom CGI scripts (details). Dada Mail is also a conceptual art project.<br />Dada Mail handles Closed-Loop Opt-in/Opt-out subscriptions, sending complex announce-only and/or discussion mailing list messages with an advanced, fault-tolerant mass mailing monitor, supports the archiving/viewing/searching/resending/syndicating (rss, atom) of sent messages and doing all this and a whole lot more with style.<br /><br />Dada Mail can handle custom subscriber fields and you can use the information it captures for partial list sending based on a query and Dada Mail's email templating system allows you to create targeted and completely custom email messages for each and every one one of your subscribers.<br /><br />Dada Mail is bundled with additional plugins and extensions to extend Dada Mail's capabilities. Some of the plugins/extensions support advanced bounce handling, clickthrough tracking, mass mail scheduling, blog interfaces of archived messages, AJAX subscription form trickery and lots of other surprises.<br /><br />Dada Mail produces XHTML valid web content and sticks to best practices when creating email messages. Write Once: Distribute Everywhere. Dada Mail is free software that you're able to use, modify, share and enhance under the terms of the GNU General Public License. Dada Mail is written in Perl because we love Perl.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-30861016633493401192009-01-22T17:48:00.000-08:002009-01-22T18:11:30.785-08:00A Logo design for Rakudo Perl 6The below is a post I started on perl6-users@perl.org and is amended by the last weeks of replies.<br /><br />I'm posting it below to garner a few more eyeballs, before I go from a, "research" stage to a, "playful" stage of trying simple things out and seeing if anything makes sense.<br /><br />If you're a part of the Perl community, I'd love to hear your input as a Kaduo Perl 6 logo may be something you'll see almost every day:<br /><blockquote><br />Hello everyone,<br /><br />A few weeks ago, probably more than I want to admit (but here! See! My Notes! I've been up to something!), there was one of those, "OMG! Perl is going to DIE!" threads, somewhere and the, "Well, do something about it" call came out, and I sort of replied, "well, alright" and gave my open ended hand to some design work.<br /><br />Moritz was one of the first to guide it to the idea of making a logo for Rakudo Perl 6 - as there's nothing yet (really) available. I thought that would be a neat project and scratch some of my person itches.<br /><br />A slight background on me: I'm that guy:<br /><br /><ul><li><a href="http://xkcd.com/519/"> http://xkcd.com/519/</a></li></ul> <br />(Although, there should be two more columns for, "Skateboarding" and, "Rock Climbing" in there). I really started working with Perl during a internship in college which started me in a full time job doin' the stuff, which got me to where I am today: just working for myself.<br /><br />In all of that, I also managed to get through Art School (guess what paid for *that*!). A lot of my work deals with language and text, writing and communication. Some of my work bordered on generative work, but most of it stayed on the canvas, as I wanted to go to school to learn to paint.<br /><br />Anyways, I've always wanted to help out on larger-than-myself Perl projects, but, although I think my perl-fu is, well, alright - it's not wizard-like. But! I think an interesting niche that I could fill is as someone who, "gets" Perl and it's wonderful and varied culture and also, "gets" visual communication and all that. I am a firm believer that a healthy community is one full of diversity and successful projects come not out of one genius, but of many just normal people, and that's me: just a normal person.<br /><br />Here's some notes I've collected about what people have said Rakudo Perl 6 is, which is a good baseline on what a logo should try to reflect and communicate:<br /><br />Rakudo Perl is:<br /><ul><li>Perl 6 on Parrot</li><li>Rakudo as a *implementation* of a *specification*</li><li>Rakuda-do (Japanese): Way of the Camel</li><li>Rakudo (Japanese): Paradise</li></ul><br />Camels, Paradise/Oasis, etc. It's good visuals and it's easy to digest. Camels are mean and smelly close up, but we don't have to get all that close - it's good to remember they're also extremely useful and in some places, absolutely critical to ways of life.<br /><br />It also doesn't stray far from the original Perl 5 image of Camels and Pyramids and all that jazz. The Japanese lean on all this seems important too, perhaps to get a little more mindshare from the folks that find Ruby interesting and attractive (more on that in just a little bit)<br /><br />One of the main fears with this name, "Rakudo Perl 6" - at least when it first came out, is that describing Rakudo Perl as, "An implementation (one of possibly, many) of the Perl 6 Specification, built on top of the Parrot Virtual Machine", will leave people going,<br /><br /><span style="font-style: italic;"> "Huh?!"</span><br /><br />I think this is a good reason as anything, to think of getting a visual representation of this, somewhat complicated idea out ASAP.<br /><br />It's interesting that Japanese Word(s) were chosen as the new name - it's grown on me - I like it. Japanese Art and Poetry has the idea of the, "haiga" and the, "gō" - which is sort of like a pen-name, but it changes if there's a change in the style of the artist during their career. You could think of, "Rakudo" as a new, "haiga" for Perl - at least the concept makes things clear to me: we've changed course, but it's still the same hand.<br /><br />I was also, incidentally, doing some research on the origins of the Latin alphabet - I'm very curious about languages in general - mostly how they're abused in media and popular culture, but also in learning new ones - I took a brief stint solo in France armed with a 5 week Free University course in French to see how well I could get along. Eye-opening.<br /><br />I happened upon the book, "Mysteries of the Alphabet" (Narc-Alain Ouknin - originally written *in* French) in the shelves of someone I was hanging out with. It's main thesis, really is the Latin/Greek alphabet started with something they term the, "Proto-Sinaitic" alphabet, which was created around the time the lost tribe of Israel was figuring itself out. Moses and all.<br /><br />One of the, well, the third letter in their alphabet is, "gimmel", which comes from the word gamel, which, if you didn't guess already means, "Camel"! It looks either like the neck of a camel - or, perhaps it's hump. If you think of, "gimmel" as our, "C" you can sort of still see a hump of a camel, if you just turn the, "C" 90 degrees, clockwise.<br /><br />Early written languages like Proto-Sinaitic are sort of the beginning where pictograms that stood for what things looked like, where changed into a way of writing about an idea - a lot of these early letters still hold a lot of the original meanings. Hebrew, for instance still does and each character is rich in back history. I like the Proto-Sinaitic link, since it's less loaded quite as intensely as Hebrew, which is invariably tied to major traditions and religions.<br /><br />The, "Gimmel" character is no exception. Start from, "Mysteries of the Alphabet"<br />------------------------------------------------------------------------------<br />:: Original Meanings<br />Carrying the Primal Power beyond, outside the domestic setting<br /><br />:: Derivative Meanings<br />Outgoing, break, carry to another, do good, return a favor<br /><br />:: Acquired Meanings, Perpetuated By The Hebrew Language<br /><br />Ripen, Ween, Enable to ripen<br />Release Oneself, Break Away From<br />------------------------------------------------------------------------------<br /><br />Which I think beautiful illustrates a nice connection between Perl 5 and Perl 6, Rakuda-do/Rakudo and haiga pen-names - and the, "Big Picture" of what exactly Perl 6 is all about - standing apart from the lineage, but still being, well, "Perl", using the Camel (gimmel) as a fundamental icon from way WAY back in time there -<br /><br />and it all sounds so Perlish of picking and choosing the best from many ideas and languages.<br /><br /><br /><br />Taking a step back from this soup of ideas and thinking of a logo itself, it seems that it would help to produce something that's made of somewhat interlocking and inter-related pieces: Perl on Parrot has two separate pieces that come together and complete an idea. But there's other things that could take, "Perl's" place, so it's really,<br /><br /> <code>$x on Parrot</code><br /><br />It seems that if a logo would be made, we can modularize, say, that Parrot part and use it for other things - same with the Perl part, if you get into it. Modularization is a way of getting ready for the future. It also allows us to be lazy: we can use other people's work already and - well, you all know this already. It would be an interesting idea to use common programming best practices in the logo of Perl itself.<br /><br />I bring that all up, because when I look at the various Perl projects, they all look extremely interesting, but fragmented. It would almost make sense to create a logo where pieces can be reused for related thingies. Starting from a logo for Rakudo Perl, one could make a simple Style Guide even, with easy-to-acquire graphic elements that say, an application written using Rakudo Perl could use (at their discretion) to enhance their own project and tie it back into Rakudo Perl (and Perl in general).<br /><br />So that's sort of the other thing I'm proposing: not only designing a logo for Rakudo Perl, but having the concept of modularization of the logo's basic elements part of the logo design itself and the sharing and remixing of the design elements for related projects, to help strengthen the, (and I'm not a fan of using this word) "branding" (sigh) of Perl and making it not so much the "invisible language that glues everything together", but have it where it belongs: in a positive light with the general (geeky) public.<br /><br />Right now, all that means to me is perhaps a simple style guide and the image and graphic resources easy to grab in open formats. This also means that simple-is-better when it comes to the design of all these different elements of the logo, as they'll be combined in interesting ways and things will have a tendency to be cluttered. Simplification also lends itself to universality: the simpler the idea is, the more we relate ourselves *to* the idea itself.<br /><br />Finally, the design of the Rakudo Perl logo should lend itself to change. Just like any other part of the project, the ideas and concept and what the darn thing actually look like should be able to move and change quickly - to be able to be upgraded - hey, why not? I'm not interested in, "owning" the design, but am more interested in playing a part in shaping the whole. And all that stuff. Just like in code, some people do more than adopt a project.<br /><br />What I really *really* need now is some feedback for any and all of the above research and braindump. This, obviously, is just one regular guy taking the first jump into something a whole lot bigger and more complex than he can even really imagine. The first step is the hardest and the most confusing - the rest of the journey is mostly, one foot in front of the other, until the end,<br /></blockquote><br />Here's a few important notes about the above:<br /><br /><span style="font-weight: bold;">Love Marks vs. Trademarks: </span><br /><br /><blockquote> Sounds like a great idea. Go for it. Here is a document I prepared for Larry Wall and the Perl Foundation about a trade mark strategy for Perl. You may find some ideas in here to help - I like your idea of interlocking imagery etc.<br /><br /><a href="http://thegoo.org/love-marks-for-perl.pdf">http://thegoo.org/love-marks-for-perl.pdf</a></blockquote>This document encourages the use of memorable, positive, <span style="font-style: italic;">interconnected </span>trademark. The Perl Foundation will be the custodian for such a mark. This is all wonderful. I don't have any problems with giving over the rights for the project to TPF and Perl at large - sort of the point, really.<br /><br />This is also a very important part of the document above:<br /><blockquote><br />If the Perl Community accidentally borrowed “The Camel” it appears O’Reilly accidentally borrowed<br />the domain name “perl.com”. Goodwill continues to accrue in the trade mark “PERL” and that<br />goodwill, including any domain names needs to be directed to its rightful owner: TPF.<br /></blockquote><br />With the Rakudo Perl 6 logo, we don't want to add even more confusion - Camels, it seems are <span style="font-style: italic;">out</span>. I wouldn't mind a gesture of a camel-like idea - for example, my gimmel idea above, but that idea may just be a stepping stone for something much large - for example, trading the Rakudo Perl 6 logo as a type of primitive written alphabet, which can be combined, with descretion with other people's and project's ideas.<br /><br />I think, at least in the "playful" stage, the camel be used as a design element, just because it could lead to more interesting things.<br /><br />BUT - Richard Dice of the Perl Foundation does make this situation absolutely clear:<br /><br /><blockquote>O'Reilly is the only organization that can have trademarks that incorporate<br />a camel in reference to the Perl programming language. This statement is a<br />first-order approximation, but damn good one. Basically, the message is:<br />stay away from using camels<br /><br /></blockquote><br /><br /><br />Patrick Michaud had this to say:<br /><br /><blockquote><br />I'll start with my summarized thoughts first, then a few specifics below.<br />First, I totally agree that Rakudo Perl needs a logo, and the sooner<br />we can get one to start using on our website (which we're now creating)<br />and other materials, the better. So, your thoughts and ideas are<br />quite welcome.<br /><br />Beyond that, I think your message has neatly captured many of the facets<br />of what we're working with (and yes, there are a lot of facets). The<br />message reminds me of some of Larry's "State of the Onion" addresses --<br />looking at many sides of the Perl (in this case Rakudo Perl 6) world.<br /><br />So, my primary comment is that I find myself very much in agreement<br />with your proposal, and a strong hope that you'll continue on in this<br />direction. I agree with the idea of the style guide and some simple<br />elements that people can combine together in very expressive and<br />beautiful ways. Indeed, it sounds very much like you're proposing<br />an ideographic system for Rakudo Perl, where can combine graphic<br />symbols for ideas together. That feels very Perlish and Rakudoish<br />to me -- I like it.<br /><br />So, I'd say "press on" and let us see what you come up with. :-)</blockquote><br />The more I think about the design problem, the more it it seems that a simple but very flexible solution would be best and that reflecting and taking the actual design process and specification of Perl 6 itself as a major influence would be a great way to go about things.<br /><br /><blockquote>I can't really speak for what Parrot will want or need, as they already<br />have a (very nice) logo. But having a symbol to represent Parrot in<br />the system you propose would likely be very workable.<br /></blockquote><br />Exactly!<br /><br />I may do more research with Patrick and see what the current needs are for a Rakudo logo and how that could be worked with a, "Grand Scheme" as well as start playfully working on some ideas.<br /><br />What I could use now is a whole lot more feedback. Sound off!Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-2118058455075556259.post-43177725393787079882008-12-01T21:14:00.000-08:002008-12-01T21:16:44.686-08:00How to handle completely clueless users?I admit I'm sort of a email traffic controller. <br /><br />It irks me to the point of a pet peeve, when I spatter the contact page of my project with notes that say, "DO NOT CONTACT ME FOR SUPPORT UNLESS YOU WANT TO BUCK UP SOME MONEY", and I get tons of support emails, wanting free support. <br /><br />Sigh. <br /><br />What I don't want to do, is take the time and go, <br /><br />"Look. We have forums. We have mailing lists. Use those. Thanks." And then not answer they're question. <br /><br />What I do is exactly that. <br /><br />I don't want to do this, because I know how much of a pain it is for the person to now, *rewrite* what they just ask me. It also is a pretty weird introduction to what should be a really valuable exchange - someone actually wants to talk to *me* about *my* thingy. <br /><br />The curious thing is, I don't want to be hired to fix some stupid bug - I have better things to do. I'd rather help fix the bug for *free* - and its beneficial - users let me know it's there, I (or them - ha!) open up a bug report, it gets fixed (probably by me) and *there's a thread of, "something just happened"* that lives far away from my inbox and takes on a life of its own. I don't have to write the same thing twice and with a little work by the user (or if they dare help themselves) they can find it themselves, and keep a thread going. When I say, "thread" - I mean, anything - a forum post about a problem, with a reply of a confirmation that it's a bug, with a link posted to a bug report, that may then give you a patch in a day or so - which then gets referred in another forum post - etc. But, a trail is there. <br /><br /><br />The thing is, there's better ways to ask the questions. <br /><br />What's the better way to point them to the right way? <br /><br /><br /><br />For a while, I just had a auto responder that said, <br /><br />"Hey, if this is a support question - go here, and here and here and read this and that and then post to this thing or that thing and away you go! America!"<br /><br /><br /><br />"...but, if this isn't a support question, well, disregard all that, and I'll get back to you, soon"<br /><br />That seemed a little foolish. <br /><br /><br />Right now, I'm trying something different - I'm just making up a mail template that first, welcomes the new person emailing me to the *community* and then gives a very brief list of resources that say, "Here's what to read", "Here's where to ask questions"<br /><br />Then, <br /><br />well, then if I can, I'll answer they're question - I haven't yet said, "And next time, POST HERE", cause again, that makes me think I'm reprimanding someone for something they may have just missed. Or something. Anyways - let's think positive and we're all humans here, and we probably all have a strong sense to belong. <br /><br />But, what I want to do is get people active in the program and community. It's pretty hard, since, well, usually my audience is general users and they just have Work They Need To Do, and aren't nerdy enough to get excited about some program. Understandably. <br /><br />Perhaps, by simply giving a welcome, some encouragement, some links to check out and a head-start on solving the problem, they'll feel as if they're welcome in a community, instead of just a bother to me. <br /><br />As far as I'm concerned, community in anything is everything. If you're not building a community, you have almost nothing, no matter how great you are, you have nothing without people. <br /><br />Anyways, I'll let you know how it goes, but I'd be interested in hearing other ideas you yourself may have,Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-64265976259023385742008-10-08T02:31:00.000-07:002008-10-08T02:36:39.128-07:00Problem with Email::Valid and newlinesFound a strange problem in Email::Valid: <br /><br /><pre> <br />#!perl<br />use strict;<br /><br />use Test::More tests => 4;<br /><br />BEGIN {<br /> use_ok('Email::Valid');<br />}<br />my $email;<br /><br />$email = 'withnewline@example.com' . "\r";<br />ok(Email::Valid->address(-address => $email) eq undef, 'addresses with "\r" at the end return undefined');<br />diag(Email::Valid->address(-address => $email));<br /><br />$email = 'withnewline@example.com' . "\r\n";<br />ok(Email::Valid->address(-address => $email) eq undef, 'addresses with "\r\n" at the end return undefined');<br />diag(Email::Valid->address(-address => $email));<br /><br />$email = 'withnewline@example.com' . "\n";<br />ok(Email::Valid->address(-address => $email) eq undef, 'addresses with "\n" at the end return undefined');<br />diag ("'" . Email::Valid->address(-address => $email) ."'");<br /><br /></pre> <br /><br />From what I expect, that last test should pass. Email::Valid's docs do say that if address can munge the address, it'll return the munged address, instead of undef - but I have munging (or "fudging, in this module" *off* - as it is off by default). Carriage returns aren't munged, so why newlines? <br /><br />Perhaps it's the last line in the module: <br /><br /><pre> <br /># Regular expression built using Jeffrey Friedl's example in<br /># _Mastering Regular Expressions_ (http://www.ora.com/catalog/regexp/).<br /><br />$RFC822PAT = <<'EOF';<br /># Possibly the most insane regex... possible<br />EOF<br /><br />$RFC822PAT =~ s/\n//g;<br /><br /></pre> <br /><br />The test for validity changes the actual string being validated. Drrrrr. <br /><br /><br />And that kind of brings up another point: Why is a module called, Email::Valid and its validating method (address) also doing double-duty with wanting to munge the string I give it so it may possibly be validated? Sounds like you just need to methods there, validate() and, gimme_back_an_address_if_at_all_possible(), <br /><br />or, <br /><br />whatever.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-84832772549126901152008-10-05T23:31:00.002-07:002008-10-05T23:37:29.985-07:00Perl Semaphores 'n stuff<p>This is a pretty good and gentle introduction into file locking and using semaphores in Perl:<br /><br /><a href="http://interglacial.com/~sburke/tpj/as_html/tpj23.html">http://interglacial.com/~sburke/tpj/as_html/tpj23.html</a><br /><br /><br /></p><p>I was having the exact problems being described:<br /><br /></p><blockquote><br /><p>Unfortunately, this means trouble for our <b>flock</b>-using code. Notably, there can still be a problem with instances being out of phase — since we can’t lock a file without already having opened it, things can still happen in that brief moment between opening the file and locking it. Consider when one instance is updating <i>counter.dat</i> just as another new instance is about to read it:</p><br /><br /><pre>Instance 1 Instance 2<br />----------------- -----------------<br />open COUNTER, ">counter.dat"<br />or die "Can't write-open: $!";<br /> open COUNTER, "<counter.dat"<br /> or die "Can't read-open: $!";<br /> flock COUNTER, LOCK_EX;<br /> my $hits = <COUNTER>;<br /> close(COUNTER);<br /><br />flock COUNTER, LOCK_EX;<br /></pre><p><br />There, the OS dutifully kept two instances at once from having an exclusive lock on the file. But the locking is too late, because instance 1, just by opening the file, has already overwritten <i>counter.dat</i> with a zero-length file, just as instance 2 was about to read it. So we’re back to the same problem that existed before we had any <b>flock</b> calls at all: two processes accessing a file that we wish only one process at a time could access.</p></blockquote>In a very very complex part of my app, that has to do with basically managing a queueing system - something that really really really should be written using a transaction capable SQL backend. If only I knew how to do that.<br /><p>I combined the semaphore file with the, Highlander, THERE CAN BE ONLY ONE! Idea:<br /><br /><a href="http://perlmonks.org/?node_id=14260">http://perlmonks.org/?node_id=14260</a><br /><br /><a href="http://www.stonehenge.com/merlyn/WebTechniques/col54.html">http://www.stonehenge.com/merlyn/WebTechniques/col54.html</a><br /><br /></p><p>So if I can't get a lock, I can wait a little longer. I thought, "Hey, sounds like a good idea". It also sorta kinda puts a queueing system to the resources that a lot of different thingies want to hit, and hopefully, stop the programming from giving back errors like, all the fucking time. We'll see.<br /></p><p>All the tests pass (you do write tests, right?), but using the app doesn't really... um, work. It's timing out. Most likely from the Highlander idea. More whackin' to do...<br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-35380856656839505622008-10-05T23:31:00.001-07:002008-10-05T23:31:32.544-07:00Nerd!I've decided what computer programming is to me at the moment:<br /><br />It's a hobby. It's a hobby that currently pays my bills, but to call it a job or a company that I have is not what's going on. I know this, because I explicitly attempt not to do what companies attempt to do really really well. One of these things is to try to sell you the product.<br /><br />The product I make is free, so there goes that baby/bathwater.<br /><br />I also write a book about the thing.<br /><br />The book is just a bunch of HTML I create from a simple doc format. It's akin to me selling you plans on how to make your own land mower from the back of Popular Mechanics, or something.<br /><br />Another thingy that companys are good at, especially in computer-stuff is automation. I do provide services to install the program. But I do it manually. There's no installer. And, that's stupid.<br /><br />But if this is just a hobby - one that takes a lot of my time, I don't have a job. And art isn't making any money.<br /><br /><br />This is all going to come to a head, soon enough. But at least it allows me to identify myself as a, "hacker" rather than a software engineer, which I couldn't possibly be.<br /><br />It also gives me something to put on my artsy résumé: Computer Hacker. That sounds almost hip. Would you like a painter that has a hobby of collecting pogs, or a painter that also has a hobby of hacking computers?<br /><br />yeah, you're right, pogs win again.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-36062553217101773292008-09-14T01:29:00.000-07:002008-10-06T01:29:50.764-07:00LWP is Simple.<p>While I'm on the nerd tip, this is the simplest example I can get to grab the contents of a URL, with a optional username/password and/or proxy: <br /><br /><pre> <br />#!/usr/bin/perl <br /> <br />my $proxy = undef; <br />my $user = undef; <br />my $pass = undef; <br />my $url = 'http://localhost'; <br /><br /> # Create a user agent object<br /> require LWP::UserAgent;<br /> my $ua = LWP::UserAgent->new;<br /><br /> if($proxy){ <br /> $ua->proxy(<br /> ['http', 'ftp'], <br /> $proxy<br /> ); <br /> }<br /> <br /> # Create a request<br /> my $req = HTTP::Request->new(<br /> GET => $url<br /> );<br /> # Pass request to the user agent and get a response back<br /> my $res = $ua->request($req);<br /> if(<br /> defined($user) && <br /> defined($pass)<br /> ){ <br /> $res->authorization_basic(<br /> $user, <br /> $pass<br /> );<br /> }<br /> # Check the outcome of the response<br /> if ($res->is_success) {<br /> return $res->content;<br /> }<br /> else {<br /> warn $res->status_line;<br /> return undef; <br /> }<br />}<br /><br /></pre> <br /><br /><p>Wishing LWP::Simple would do this, but. Nope.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-4281807918104741902008-09-13T01:30:00.000-07:002008-10-06T01:31:39.462-07:00MIME Trickery with MIME::Parser and friends<p>You can attach attachments to a multipart/related email message entity (say, a email message created from a website, with the images attached to the message itself) by creating a new multipart/mixed entity, and having the first part be that multipart/related entity and the rest being your new attachments. For example: <br /><br /><pre> <br />#!/usr/bin/perl <br />use strict; <br /><br />use :MyMIMELiteHTML; <br />use MIME::Parser; <br />use MIME::Entity; <br /><br />my $HTMLurl = 'http://localhost'; <br />my $jpg_path = '/Users/justin/Desktop/4.jpg';<br /><br /><br />my $mailHTML = new MyMIMELiteHTML(<br /> 'IncludeType' => 'cid', <br />); <br /> <br />my $MIMELiteObj = $mailHTML->parse($HTMLurl) ;<br /><br /> <br />my $msg_as_string = $MIMELiteObj->as_string; <br /><br /><br />my $parser = new MIME::Parser;<br /><br />my $entity = $parser->parse_data($msg_as_string);<br /><br /><br /># Attach stuff to it:<br /><br /><br />my $cont_entity = MIME::Entity->build(Type => "multipart/mixed");<br /> $cont_entity->add_part($entity); <br /> $cont_entity->attach(<br /> Path => $jpg_path,<br /> Type => "image/jpg",<br /> Encoding => "base64",<br /> Disposition => "attachment",<br /> );<br /><br />print $cont_entity->stringify;<br /></pre> <br /><br /><br /><p>MyMIMELiteHTML is just my version of MIME::Lite::HTML, with a few bug fixes and changes to fit in my program better. <br /><br /><br /><p><a href="http://search.cpan.org/~alian/MIME-Lite-HTML-1.22/HTML.pm">http://search.cpan.org/~alian/MIME-Lite-HTML-1.22/HTML.pm<br /></a><br /><br /><p>I've tried also just added the attachments to the multipart/related entity, but the new attachments never can be found - at least in Mail.app (Gmail? Yes?), unless you put in a bogus Content-ID header for the attachement - which actually could come in handy in some rare cases, but I digress...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2118058455075556259.post-2717474195686248132008-04-08T22:28:00.000-07:002008-04-08T22:38:59.416-07:00First Post. It's about Perl. Perl Perl Perl.So. <br /><br />There was a recent flurry of postings in the Perl Community dealing with how Perl isn't very sexy any more and lots of, "oh my God, no one uses Perl anymore" and sky falling down and all that. <br /><br />They also mentioned that the number of teh blogs dealing with Perl, when compared to other languages was a bit lackluster. Perhaps this is because most of the big-shot Perl programmers you see lurking around on teh Perl mailing lists and are creating the majority of quality CPAN modules are on http://use.perl.org? - I dunno. <br /><br />Anyways, I thoughts to myself, Self, you're eccentric. You're a sexy little beast. <br /><br />And you program in Perl. <br /><br />So here's my hat thrown into the ring for teh Blogs about teh Perl.<br /><br />The other thing I do - I would say my main passion is Art: drawing and painting. It's not Perl. Perl helps pay the bills I guess. <br /><br />I'm sort of realizing, as I get older, that playing with Perl and being so SO into art is a rarity, and as a nod to the Paul Graham article, "Hackers and Painters (http://paulgraham.com/hp.html)", I give you the Perl Hacker Painter. <br /><br />Hacking is probably the best way to describe to you how I program. I barely understand the concepts I play around with. I didn't go to school for this. I am not math-inclined. <br /><br />But, I've flourished, in my own little way, in writing Perl (mostly). <br /><br />If you're more traditional in your skill-acquiring, I may say/do/write things that makes no sense. And, that's OK. Because, when I ask for help? I get a lot of answers from people that don't make much sense to me. And then, I just hack about.<br /><br /><br />I'll probably use this thing (I loathe the word, blog) to write examples of code for whatever, problems I solved with Perl and hopefully, artwork Perl helped me with, since, there's a lot of that in my portfolio <br /><br />So, if you're zooming around on Techorati or something and you've come across, *gasp* a blog about Perl, well, hello to you too.Unknownnoreply@blogger.com0