Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

eng21337 -- A Pidgin plugin

by Lawliet (Curate)
on Jan 25, 2009 at 01:45 UTC ( #738740=CUFP: print w/ replies, xml ) Need Help??

Update: Added some things, removed some things, the new version is a reply to this node.

Well, I was very excited when I learned that Pidgin accepts plugins written in Perl. (This is my 3rd plugin, the first two being far from complete.) I was not so excited to learn that the best documentation they have is for C (which I do not know). That being said, if there are better ways to do something, please let me know.

I tried to keep the lines to 80 columns (which, before previewing, I thought PM used to keep code tags from being too long. I now realize that the limit is less than 80 characters.)~

# English 2 13375p34k # TODO (in order of importance) # Convert &amp; (and such) to & (and such). # Set up preferences to allow user customization of the substitutio +ns use warnings; use strict; use Purple; use Acme::LeetSpeak; # Who says Acme should not be used in production +:P our %PLUGIN_INFO = ( perl_api_version => 2, name => "eng21337", version => "0.1.3", summary => "Anything you type (that is in <leet></leet> tags) will + betranslated to leetspeak and then sent.", description => "Anything you type (that is in <leet></leet> tags) +will be translated to leetspeak and then sent. I use the Acme::LeetSp +eak module (which does all the work :)). Please note that Pidgin conv +erts '&' to '&amp' so the leetspeak of 'me&you' will be 'm3&4Mpjo0' ( +or something). I'll fix it in a later version ;)", author => "Marc Green", url => "http://pidgin.im", load => "plugin_load", unload => "plugin_unload", ); my $pathname = '/plugins/core/eng21337'; my $catchloop = 0; # Used to stop infinite loop below (there is probab +ly a way # to avoid the whole thing but this works for now : +P) sub plugin_init { return %PLUGIN_INFO; } sub plugin_load { my $plugin = shift; # Everytime I send an im, call the subroutine sending_im_msg_cb my $convs_handle = Purple::Conversations::get_handle(); Purple::Signal::connect($convs_handle, "sending-im-msg", $plugin, \&sending_im_msg_cb, ''); Purple::Debug::info("eng21337", "plugin_load() - eng21137 plugin l +oaded\n"); } sub plugin_unload { Purple::Debug::info("eng21337", "plugin_load() - eng21137 plugin l +oaded\n"); } sub sending_im_msg_cb { my ($account, $who, $msg) = @_; $catchloop++; # Everytime I send() something from this subroutine (sending_im_ms +g_cb) # this subroutine gets called again (because I am send()ing someth +ing) # leading to an infinite loop. This is why I use $catchloop. I set + it to 0 # earlier so when this sub is called it will increase to 1 letting + the # below if statement execute. It is then set to 0 to restart the p +rocess. # This stops the infinite loop because once I call $im->send($msg) +, this # sub gets called again making $catchloop 2 which bypasses the if +statement # including the send(). Trust me, I've done the math. if ($catchloop == 1) { my $reg = qr{ &lt;leet&gt; # <leet> -- Pidgin converts <> + to html (.+?) # Stuff to be leet'd &lt;/leet&gt; # </leet> }x; $msg =~ s/$reg/leet($1);/ge if $msg =~ /$reg/; # Not sure how else to get the correct im handle besides these + 5 lines my $im; my @convs = Purple::get_conversations(); foreach my $conv (@convs) { $im = $conv->get_im_data() and last if $conv->get_name eq +$who; } $im->send($msg); # Show *both* users the leetspeak'd message $_[2] = ''; # Prevent double messages } $catchloop--; }

Put it in your ~/.purple/plugins folder (create if necessary), restart Pidgin, and enable it through Tools->Plugins.

Oh, and, to use it, just put any text you want turned into leetspeak between <leet></leet> tags.

Thanks to jdporter for the <leet></leet> tags suggestion. Thanks to the author of Acme::LeetSpeak for obvious reasons. (Make sure to download that module, by the way.)

Also, plans for eng2LOLCAT have been made: .oO( I think 3 or 4 substitutions and a download of Acme::LOLCAT will be all that is needed :P )

And you didn't even know bears could type.

Comment on eng21337 -- A Pidgin plugin
Download Code
Re: eng21337 -- A Pidgin plugin
by atcroft (Monsignor) on Jan 25, 2009 at 09:58 UTC

    Interesting post. Regarding your first TODO note, HTML::Entities's decode_entities() function (or, perhaps, the two-element _decode_entities() function) look like a possible solution for you. The decode_entities() function would replace any entity; the two-element _decode_entities() function allows you to specify which entities should be decoded.

    HTH.

      Interesting post.

      .oO( Interesting does not necessarily mean good :P )

      Thank you for the suggestion -- I just try to keep the number of used modules to a minimum to save the user the hassle of installing them.

      And you didn't even know bears could type.

        In this case, "interesting" was that I was just looking a week or two ago at the plugin system, but didn't have time for more than a cursory look, so this gave me something I can experiment from (when I again have some free time).

        As to your trying to keep modules to a minimum, I can understand that, but I think this would give you more flexibility for later, if you decide you want to decode more than just &amp; . Just my humble opinion, though, and I'm open to there being other considerations I may be missing. If nothing else, it might be worth a look at "borrowing" the appropriate code, as an option.

        HTH (and good post).

Re: eng21337 -- A Pidgin plugin
by Lawliet (Curate) on Jan 25, 2009 at 21:40 UTC

    I added some preferences. One can now specify their own tag to be used (instead of being forced to use <leet></leet>, you can now use <LOLOLOL></LOLOLOL>, or whatever.) Also, I added an option to be in "Full Leet" mode. Enabling this option translates everything the user types to leet. That's right, everything -- no <leet></leet> tags required! In fact, if you put the <leet></leet> tags there, they will be turned into leetspeak (but Pidgin encodes the less than and greater than signs so it looks dumb)! Are you ready to unleash the fury? Oh, I also changed the wording of some things and such.

    The full plugin is below.

    # English 2 13375p34k # TODO (in order of importance) # Convert &amp; (and such) to & (and such). # Set up preferences to allow user customization of the substitutio +ns use warnings; use strict; use Purple; use Acme::LeetSpeak; # Who says Acme should not be used in production +:P our %PLUGIN_INFO = ( perl_api_version => 2, name => "eng21337", version => "0.2.1", summary => "Translate what you type to leetspeak.", description => "Anything you type (that is (optionally) between <l +eet></leet> tags (the tags are customizable, though)) will be transla +ted to leetspeak and then sent. I use the Acme::LeetSpeak module (whi +ch does all the work :)). Please note that Pidgin converts '&' to '&a +mp' so the leetspeak of 'me&you' will be 'm3&4Mpjo0' (or something). +I'll fix it in a later version ;)", author => "Marc Green", url => "http://pidgin.im", load => "plugin_load", unload => "plugin_unload", prefs_info => "prefs_info_cb", ); my $pathname = '/plugins/core/eng21337'; my $catchloop = 0; # Used to stop infinite loop below (there is probab +ly a way # to avoid the whole thing but this works for now : +P) sub plugin_init { return %PLUGIN_INFO; } sub plugin_load { my $plugin = shift; Purple::Prefs::add_none($pathname); Purple::Prefs::add_string("$pathname/leet_tag", "leet"); Purple::Prefs::add_bool("$pathname/full_leet", 1); # Everytime I send an im, call the subroutine sending_im_msg_cb my $convs_handle = Purple::Conversations::get_handle(); Purple::Signal::connect($convs_handle, "sending-im-msg", $plugin, \&sending_im_msg_cb, ''); Purple::Debug::info("eng21337", "plugin_load() - eng21137 plugin l +oaded\n"); } sub plugin_unload { Purple::Debug::info("eng21337", "plugin_load() - eng21137 plugin l +oaded\n"); } sub prefs_info_cb { my ($frame, $ppref); $frame = Purple::PluginPref::Frame->new(); $ppref = Purple::PluginPref->new_with_name_and_label("$pathname/le +et_tag", "Tag used to denote what should be turned into leetspeak.\n(E. +g., type 'dood' if you want to use <dood></dood>."); $ppref->set_type(2); $ppref->set_max_length(9); $frame->add($ppref); $ppref = Purple::PluginPref->new_with_name_and_label("$pathname/fu +ll_leet", "Always in leetspeak mode. (I.e., no <leet></leet> tags\nneede +d -- everything you type will be translated.)"); $frame->add($ppref); return $frame; } sub sending_im_msg_cb { my ($account, $who, $msg) = @_; my $leet_tag = quotemeta Purple::Prefs::get_string("$pathname/leet +_tag"); my $full_leet = Purple::Prefs::get_bool("$pathname/full_leet"); $catchloop++; # Everytime I send() something from this subroutine (sending_im_ms +g_cb) # this subroutine gets called again (because I am send()ing someth +ing) # leading to an infinite loop. This is why I use $catchloop. I set + it to 0 # earlier so when this sub is called it will increase to 1 letting + the # below if statement execute. It is then set to 0 to restart the p +rocess. # This stops the infinite loop because once I call $im->send($msg) +, this # sub gets called again making $catchloop 2 which bypasses the if +statement # including the send(). Trust me, I've done the math. if ($catchloop == 1) { # If the user wants everything translated to leetspeak, do so. # Else, just translate stuff between the tags if ($full_leet) { $msg = leet($msg); } else { my $reg = qr{ &lt;$leet_tag&gt; # <leet> (.+?) # Stuff to be leet'd &lt;/$leet_tag&gt; # </leet> }x; $msg =~ s/$reg/leet($1);/ge if $msg =~ /$reg/; } # Not sure how else to get the correct im handle besides these + 5 lines my $im; my @convs = Purple::get_conversations(); foreach my $conv (@convs) { $im = $conv->get_im_data() and last if $conv->get_name eq +$who; } $im->send($msg); # Show *both* users the leetspeak'd message $_[2] = ''; # Prevent double messages } $catchloop--; }

    It seems, when viewing the code from the download button, the formatting is not what I had intended it to be. I think I mixed spaces and tabs :O -- sorry about that.

    And you didn't even know bears could type.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://738740]
Approved by GrandFather
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2015-07-02 00:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (25 votes), past polls