templink.pm 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # Provides a facility for creating temporary shortened links.
  2. # Plugins call this to generate a shortened link; a control client can
  3. # retrieve the long URL given the keyword from the shortened one.
  4. use POSIX;
  5. my %links = ();
  6. my $chars = '023456789abcdefghkmnopqrstuvwxyz';
  7. my $numchars = length($chars);
  8. my $int_to_str = sub {
  9. my $i = shift;
  10. my $res = '';
  11. while ($i > 0) {
  12. $res = substr($chars, $i % $numchars, 1) . $res;
  13. $i = POSIX::floor($i/$numchars);
  14. }
  15. $res;
  16. };
  17. my $str_to_int = sub {
  18. my $str = shift;
  19. my $i = 0;
  20. while (length($str)) {
  21. $i = $i * $numchars + index($chars, substr($str, 0, 1));
  22. $str = substr($str, 1);
  23. }
  24. $i;
  25. };
  26. {
  27. schemata => {
  28. 0 => [
  29. "CREATE TABLE templinks (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  30. url TEXT NOT NULL)",
  31. ],
  32. },
  33. functions => {
  34. make => sub {
  35. my $url = shift;
  36. eval {
  37. $BotDb::db->do("INSERT INTO templinks (url) VALUES(?)", {}, $url);
  38. };
  39. if ($@) {
  40. return undef;
  41. }
  42. my $id = $BotDb::db->last_insert_id(undef, undef, "templinks", "id");
  43. my $tag = $int_to_str->($id);
  44. $links{$tag} = $url;
  45. return $BotIrc::config->{templink_baseurl} . $tag;
  46. },
  47. },
  48. control_commands => {
  49. 'templink_get' => sub {
  50. my ($client, $data, @args) = @_;
  51. if (!exists $links{$args[0]}) {
  52. my $id = $str_to_int->($args[0]);
  53. my $res = $BotDb::db->selectrow_hashref(
  54. "SELECT url FROM templinks WHERE id = ?", {}, $id);
  55. if (!defined $res) {
  56. if (defined $BotDb::db->err) {
  57. BotCtl::send($client, "error", "db_error", $BotDb::db->errstr);
  58. BotIrc::error("templink: fetching link $args[0]=$id: ".$BotDb::db->errstr);
  59. return;
  60. }
  61. $client->put("error:notfound");
  62. return;
  63. }
  64. $links{$args[0]} = $res->{url};
  65. }
  66. BotCtl::send($client, "ok", $links{$args[0]});
  67. },
  68. },
  69. irc_commands => {
  70. 'shorten' => sub {
  71. my ($source, $targets, $args, $account) = @_;
  72. BotIrc::check_ctx(authed => 1) or return;
  73. my $nick = BotIrc::nickonly($source);
  74. my ($url) = split(/\s+/, $args);
  75. my $outurl = BotPlugin::call('templink', 'make', $args);
  76. BotIrc::send_noise(".shorten: out $outurl in $url");
  77. },
  78. },
  79. };